This page starts with the message shown in the terminal. Find the exact string for your case and follow the fix. All messages below are the actual strings from cli/src/cli.ts and packages/core/src/maleta.ts; nothing here is paraphrased.
#maleta: command not found
Symptom. The shell responds with maleta: command not found (or equivalent) for any command.
Cause. The maleta CLI is not installed globally, or npm's binary directory is not in PATH.
Fix. Install the package from npm:
npm install -g maleta.dev
maleta --helpNode >=20 is the requirement declared in engines, but it is only advisory: there is no runtime version check. If the command is still unavailable after installation, make sure npm's global binary directory is in PATH.
#unknown command 'tray'
Symptom. Running maleta tray prints [error] unknown command 'tray' and exits with code 2.
Cause. The installed package predates tray support. Identify the global installation with npm ls -g maleta.dev --depth=0; an old release may not support maleta --version.
Fix. Update the global package with npm install -g maleta.dev@latest, then run maleta tray again.
#tray icon creation failed: <error>
Symptom. On Linux, maleta tray reports a tray icon creation failure with guidance about D-Bus and StatusNotifierItem, then exits with code 4.
Cause. The desktop session has no available StatusNotifierItem host, or the tray process cannot reach its session D-Bus. KDE panels normally provide a host; GNOME needs an AppIndicator extension.
Fix. Enable the panel tray or AppIndicator extension and confirm that session D-Bus is available. Do not run the tray through SSH or in a headless session unless that session provides a StatusNotifierItem host.
#unknown option '<x>'
Symptom. stderr shows unknown option '<x>' followed by Run 'maleta --help' for usage., and the exit code is 2.
Cause. The flag does not exist or is not valid in that position. Command options are --file, --tool, --dry-run, and --help (or -h). maleta --version is supported only as an isolated command. There is no -f, -t, -v, --force, or --quiet, and the file is not accepted as a positional argument.
Fix. Use the supported flag instead: maleta validate --file ./maleta.json. Remember that --file is resolved against the cwd, so the relative path must be valid from the directory where the command runs.
#--tool must be all, claude, codex, or agents
Symptom. The message --tool must be all, claude, codex, or agents appears and the process exits with code 2.
Cause. The value passed to --tool is not part of the enum, or the flag was used with init — in that case, the message is --tool is only supported by install and sync. --tool applies to install and sync.
Fix. Use one of the four values: all, claude, codex, or agents. If you want the target specified in the file, omit the flag: targetTool is used automatically.
#refusing to overwrite existing file: <path>
Symptom. maleta init prints [error] refusing to overwrite existing file: <caminho> and exits with code 3.
Cause. The destination file already exists. init opens it with openSync(target, "wx"), which fails with EEXIST instead of overwriting it.
Fix. Choose another path with --file (maleta init --file ./nova-maleta.json) or deliberately remove the existing file. If the error is [error] could not create <path>: <msg> with code 1, the parent directory probably does not exist — create it before running init, because the CLI does not create the file path's directory tree.
#Invalid Maleta JSON
Symptom. [error] <caminho>: JSON de Maleta inválido with exit code 1.
Cause. The file contents are not valid JSON: a trailing comma, comment, single quotes, unquoted key, or a . instead of :. The entire JSON document is read before any schema validation.
Fix. Compare it with the canonical example in Schema and run maleta validate --file ./maleta.json again. A document exported by the builder is already in the correct format: JSON.stringify(doc, null, 2) with a trailing newline.
#Maleta must expose skills, plugins, targetTool, and targetOs at the top level
Symptom. [error] <caminho>: Maleta precisa expor skills, plugins, targetTool e targetOs no nível principal.
Cause. At least one of the following is missing from the root: slug, skills, plugins, targetTool, or targetOs — or the selection is inside a selection object. In the latter case, the message is Formato de Maleta inválido: os campos da seleção devem ficar no nível principal.
Fix. Move the selection fields to the top level and declare all required fields. The lists may be empty, but they must exist: "skills": [] and "plugins": [] are valid. If the error is Formato de Maleta não suportado, set schemaVersion to 1: there is no migration between versions.
#targetOs '<x>' does not match the local host '<y>'; refusing <mode>
Symptom. [error] targetOs 'windows' does not match the local host 'unix'; refusing install (or refusing sync), with exit code 4.
Cause. The document declares an operating system that differs from the host. The manifest is portable, but execution is not: install and sync refuse to modify destinations that do not match the machine where they are running. validate does not perform this check.
Fix. Set targetOs in the file to match the host, or run it on a machine that matches the declared value. Note that the same mismatch exits with 4 through the CLI and throws PlanError — which becomes exit 1 — when createInstallPlan is used as a library.
#target directory collision '<name>' between <prev> and <src>
Symptom. [error] target directory collision 'reviewer' between builtin:reviewer and github:reviewer, before any network request.
Cause. Two selected skills are competing for the same directory name at the destination. The directory name is the skill's name, so a built-in skill and a GitHub skill with the same name collide even if they have different id values. On Windows, the comparison is case-insensitive, and reserved device names (CON, NUL, COM1…LPT9) also fail with unsafe target directory name: <name>.
Fix. Rename one of the two entries in maleta.json so that the directory names are distinct. The name of a built-in source must still match the skill name; for the GitHub skill, name can be any value.
#GitHub repository not found: <repo>
Symptom. [error] GitHub repository not found: acme/skills.
Cause. The CLI made a diagnostic request to the specified repository and received 404. The repo does not exist, is private, or was entered incorrectly. The normalized value is always owner/name, without the scheme or .git.
Fix. Verify the repository in repo — owner/name or the URL https://github.com/owner/name — and try again. Private repositories are not supported through this path.
#GitHub ref not found: <ref>
Symptom. [error] GitHub ref not found: v1.2.0.
Cause. The repository exists, but the ref value does not match any branch, tag, or SHA. For 40-character hexadecimal refs, the CLI probes only the commits endpoint; for all others, it probes heads and tags.
Fix. Change the ref to an existing branch or tag. If the goal was to track the default branch, omit the field—but read the warning about mutable branches in GitHub Skills.
#GitHub skill path not found: <path>
Symptom. [error] GitHub skill path not found: skills/reviewer.
Cause. The repository and ref were found, but the specified path does not exist in that revision. This message is the most specific in the chain: the CLI only emits it after ruling out a missing repository and ref.
Fix. Check the relative path within the repository. It is case-sensitive, uses / as the separator, and does not accept a leading slash.
#skill path not found: <p> (SKILL.md is required)
Symptom. [error] skill path not found: skills/reviewer (SKILL.md is required).
Cause. The directory was resolved and the files were downloaded, but none of them is named SKILL.md (case-insensitive comparison). The file is the marker that identifies the root of a skill; without it, the CLI does not materialize anything.
Fix. Point path to the directory containing SKILL.md or specify the file itself—a path ending in SKILL.md is automatically reduced to its parent directory.
#GitHub access denied or rate limited
Symptom. [error] GitHub access denied or rate limited.
Cause. The response was 401 or 403. Both conditions produce the same string: an invalid token or the anonymous request limit has been exceeded. The CLI does not read headers such as Retry-After, so it does not distinguish between the cases and does not wait before trying again.
Fix. Set GITHUB_TOKEN to a valid token and run the command again manually: GITHUB_TOKEN=ghp_exemplo maleta install --file ./maleta.json. The header is only sent to api.github.com, github.com and raw.githubusercontent.com; any other host is rejected with refusing GitHub token on a non-GitHub host. See Environment variables for details.
#network timeout
Symptom. [error] network timeout.
Cause. A request exceeded the 10-second per-request limit and was aborted. There is no retry or backoff: resolution fails on the first slow attempt.
Fix. Check connectivity to api.github.com, try again, and, if the repository is large, reduce the skill's file set. Because the entire plan is aborted before anything is written, a second run does not encounter partial state.
#skill exceeded maximum size (5242880 bytes)
Symptom. [error] skill exceeded maximum size (5242880 bytes) or, for an individual file, [error] skill file exceeded maximum size: <path>.
Cause. The total bytes in the resolved tree exceeded 5 MiB, or an individual file does not fit within the remaining budget. The total is accumulated as the tree is traversed.
Fix. Reduce the contents of the directory specified by path in the source repository, or specify a smaller subdirectory. The limit is per skill, so splitting the selection into multiple entries helps when the source allows it.
#skill exceeded maximum file count (200)
Symptom. [error] skill exceeded maximum file count (200).
Cause. The resolved tree contains more than 200 files. The count includes all regular files found recursively from the specified directory.
Fix. Point path to a more specific directory or remove auxiliary skill files at the source. The two skill limits are independent — see the full table in Limits.
#destination path contains a symlink: <path>
Symptom. [error] destination path contains a symlink: /home/<usuário>/.claude.
Cause. A segment of the path to the destination is a symbolic link. The CLI validates each segment with lstatSync and refuses to write through a symlink to avoid writing outside the expected tree. The related check is destination is not a directory: <path>, when the segment exists but is not a directory.
Fix. Replace the link with a real directory or run with MALETA_CLI_HOME pointing to a tree without symlinks: MALETA_CLI_HOME=/tmp/qa-home maleta install --file ./maleta.json.
#The skill did not appear in the tool
Symptom. install or sync completes successfully, but the skill does not appear in the tool's list.
Cause. There was probably a [skip] …. The possible cases are: [skip] builtin skill '<name>' is not present in claude/skills; not installed (the name does not exist in the packaged assets), [skip] plugin '<id>' is Claude-only and is unsupported for --tool <tool> and [skip] plugin '<id>' is not present in the local plugin manifest; not installed. Skipped items do not change the exit code: the run still exits with 0.
Fix. Read the output line by line and confirm the correct destination: claude writes to ~/.claude/skills/<name>/, while codex and agents write to ~/.agents/skills/<name>/. Then restart the tool: the list of skills and plugins is loaded when the session starts. The complete path reference is available in Paths.
#Computer already has a credential
Symptom. [error] este computador já tem uma credencial; rode 'maleta logout' primeiro (exit code 3).
Cause. The computer already holds credentials in .maleta/credentials.json. Running maleta login again refuses to overwrite existing authorized credentials.
Fix. If you want to re-authorize or switch accounts, run maleta logout first, then run maleta login again.
#Computer is already bound to a Maleta
Symptom. [error] já existe uma Maleta vinculada; rode 'maleta detach' primeiro (exit code 3).
Cause. The computer is currently bound to another Cloud Maleta. V1 allows exactly one bound Maleta per computer.
Fix. Unbind the current Maleta by running maleta detach, then run maleta attach <maleta> with the new Maleta.
#Multiple Cloud Maletas share this name
Symptom. [error] mais de uma Maleta com este nome; use o id: maleta attach <id> (exit code 1).
Cause. You specified a slug or name in maleta attach that matches more than one Cloud Maleta in your account.
Fix. Look up the specific Maleta's UUID on app.maleta.dev/maletas and attach using the ID: maleta attach <uuid>.
#A maleta watch is already running
Symptom. [error] há um 'maleta watch' em execução neste computador (pid <pid>); pare o watch antes de remover (exit code 3).
Cause. maleta prune --yes requires the exclusive watch lock (.maleta/watch.lock) to prevent deleting files while a reconciliation pass is active.
Fix. Stop the background maleta watch process (or wait for it to finish), then run maleta prune --yes. You can preview candidate files at any time with maleta prune --dry-run without needing to stop watch.
#Device state could not be read
Symptom. [error] o estado deste computador não pôde ser lido; nada será removido.
Cause. .maleta/state.json is missing, invalid, or corrupted. To protect user files from accidental deletion, prune turns off all deletion paths when the state cannot be verified.
Fix. Run maleta watch --once to regenerate a fresh state file from the bound Cloud Maleta.
#Cloud Maleta limit reached (3 per account)
Symptom. The web workspace warns with You reached the limit of 3 Maletas on the account (or API code limit_reached) when attempting to save a Maleta to the account.
Cause. Each account can store up to 3 Cloud Maletas on the server.
Fix. Open app.maleta.dev/maletas, click on an existing Cloud Maleta, and remove it from the account if no longer needed, or keep your additional Maletas stored locally in the browser (which holds up to 50 Maletas).
#Cloud Maleta changed on another device
Symptom. The web workspace alerts with This Maleta was changed on another device (or API code conflict) when trying to save changes.
Cause. Optimistic concurrency control detected that another device updated the Cloud Maleta revision since you opened it.
Fix. Use the actions presented on the row: choose "Reload from cloud" to adopt the remote changes, or "Save as copy" to preserve your local modifications as a new Maleta.