Skip to content

daemon start reports an invalid config.json as INTERNAL (exit 1), not a request error (exit 2) #1084

Closed

Description

@V3RON

What happened

simlock daemon start refuses a config.json that fails validation with code INTERNAL and exit 1:

  • --gateway daemon start with http.enabled: false in the gateway's config.json:
    {"error":{"code":"INTERNAL","message":"Invalid config value for \"http.enabled\": expected true in gateway mode (a gateway is reached over HTTP)"}}
  • --local daemon start on a joined worker (gateway.url set) with http.enabled: true:
    {"error":{"code":"INTERNAL","message":"Invalid config value for \"http.enabled\": expected false when gateway.url is set (joined workers are reached through the gateway)"}}

What you expected

A wrong config value is a wrong request, not an internal failure: exit 2 with a request-error code, as simlock config set already does for the same values (website docs, worker/configuration: "refused with exit code 2"). Rerunning unchanged fails again, which is what exit 2 means in the errors reference.

How to reproduce

The two unit tests in src/cli/index.test.ts ("starting a gateway refuses to launch when its config.json fails gateway validation" and "--local daemon start with no daemon listening refuses a joined worker's HTTP conflict before any launch") assert only not.toBe(0); changing them to toBe(2) fails on main.

Environment

main at 1eff6b8, found by the test audit in #1039.

Logs and evidence

See above.

Written by an agent.

Activity

  1. added
    bug:newReported. An agent may triage it (rule 8), and nothing more.
    on Oct 30, 2026
  2. self-assigned this
    on Oct 31, 2026
  3. V3RON commented on Oct 31, 2026

    @V3RON
    ContributorAuthor

    Reproduction

    Confirmed on main at ce8fea8. The two tests the issue names now assert exit 2 and { code: "USAGE", message } with the message unchanged. Both fail with exit 1. Branch bug/1084-repro, src/cli/index.test.ts:

    • "--gateway daemon start refuses a config.json that fails gateway validation with exit 2 and USAGE, before any launch"
    • "--local daemon start with no daemon listening refuses a joined worker's HTTP conflict with exit 2 and USAGE, before any launch"
    pnpm exec vitest run --project unit src/cli/index.test.ts -t "exit 2 and USAGE, before any launch"
    AssertionError: expected 1 to be 2   (index.test.ts:3384, :3472)
    Tests  2 failed
    

    Root cause

    Defect. AutoLaunchAdminConnector.connect calls checkConfig() at src/cli/environment.ts:54 (defined at :294). That call runs loadConfig, and the ConfigError it throws reaches runCli's error boundary unwrapped. ConfigError is neither a UsageError nor a SimlockError, so cliErrorCode returns INTERNAL (src/cli/errors.ts:53) and errorExitCode returns 1 (:62). config set wraps the same error in UsageError (src/cli/commands/config.ts:52). The symptom shows up in daemon start, but the cause is in the shared auto-launch path: every auto-launching command (status, lease, ...) is affected.

    Simplest fix

    In checkConfig (environment.ts:294), catch ConfigError and rethrow it as new UsageError(error.message). Export ConfigError from src/core/index.ts, where it is not exported today. USAGE follows the config set precedent. It is the code the test pins.

    Alternatives rejected

    • Map every checkConfig error to USAGE: a read failure such as EACCES is not a wrong request.
    • Map ConfigError by name in errors.ts: the error stays a core class that the CLI only recognises by name, and the boundary gets one more lazy check.
    • Use BAD_REQUEST: that code means a daemon refused a request. Here no daemon was reached.

    Risk

    • Invalid JSON in config file is also a ConfigError, so it becomes exit 2 as well. Intended.
    • The DAEMON_STARTUP_FAILED row in website/.../using-devices/errors.mdx:75 says a bad config file is a common cause. After this fix, the CLI precheck reports a bad config as USAGE, so that row needs updating.
    • lazy-loading.test.ts: importing ConfigError must not load core on the router path.

    Written by an agent.

  4. removed their assignment
    on Oct 31, 2026
  5. added
    bug:readyAn agent may fix it.
    and removed
    bug:newReported. An agent may triage it (rule 8), and nothing more.
    on Oct 31, 2026
  6. self-assigned this
    on Oct 31, 2026
  7. added a commit that references this issue on Oct 31, 2026
    45475ff
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bug:readyAn agent may fix it.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions