Skip to content

cants exits 0 on FATAL and on a nonexistent input path, writing an empty-application analysis.json #181

Description

@rahlk

Problem

cants exits 0 when it fails. Two cases, both measured on 1.3.0:

$ cants -i /nonexistent/xyz -o out ; echo "rc=$?"
rc=0
$ cat out/analysis.json     # written anyway
{"schema_version":"2.0.0","language":"typescript","max_level":1,
 "analyzer":{"name":"codeanalyzer-typescript","version":"1.3.0"},
 "application":{"id":"can://typescript/xyz","kind":"application","symbol_table":{}, ...}}
$ cants -i vscode -o out ; echo "rc=$?"
[codeanalyzer-ts] FATAL TypeError: Type error
    at structuredClone (unknown)
    at finalizeAnalysis (...)
rc=0

So the analyzer returns success after printing FATAL, and returns success for an input path that does not exist — emitting a schema-valid payload describing an empty application, whose id is derived from the last path segment of a directory that was never read.

Why it matters

Every consumer runs this as a subprocess and the exit code is the only cheap health signal. A wrapper written the obvious way — subprocess.run(..., check=True) — treats both cases as a successful run. The nonexistent-path case is worse than the crash, because it hands back a well-formed payload: an agent asking "what does this project contain?" is told, in schema-conformant JSON, that the answer is nothing.

The FATAL case is at least distinguishable by the absent output directory, and the empty-input case by symbol_table == {} — but both require the consumer to know to look, and neither is what an exit code is for.

Expected

  • A nonexistent or unreadable -i path is an error: non-zero exit, no analysis.json written.
  • Any path that prints FATAL exits non-zero.

An empty symbol_table should mean "this project has no analysable sources", which is a real and different answer from "the input did not exist".

Environment

codeanalyzer-typescript 1.3.0 (PyPI wheel, bundled Bun binary), macOS 15 arm64.

Related: the crash in the second case is #180. This issue is about the exit code and the payload, which are independent of what went wrong.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions