Tools
CLI
Use the Featurevisor CLI to set up a project, validate definitions, build datafiles and investigate evaluation results.
Commands below use the buyButton feature with its label variable and variations, and the supportEmail global variable, both from the Variables guide. Substitute keys and context from your project when using these commands elsewhere.
Command overview#
| Task | Command | Purpose |
|---|---|---|
| Set up | init | Create a project in an empty directory. |
| Set up | config | Print the resolved project configuration. |
| Set up | help | Show commands and their options. |
| Set up | version | Print CLI and package versions. |
| Validate | lint | Check definitions and test specifications. |
| Validate | test | Run feature, segment, variable and scenario tests. |
| Build | build | Generate JSON datafiles for targets and environments. |
| Build | generate-code | Generate typed TypeScript APIs from definitions. |
| Inspect | catalog | Browse locally, export or serve a Catalog. |
| Inspect | list | List definitions, datafiles and tests. |
| Inspect | info | Summarize project counts and selected datafile sizes. |
| Inspect | find-duplicate-segments | Find segments with identical conditions. |
| Inspect | find-usage | Trace references and find unused definitions. |
| Evaluate | evaluate | Evaluate a feature or variable for a context. |
| Evaluate | benchmark | Measure local evaluation performance. |
| Evaluate | assess-distribution | Simulate rollout and variation distribution. |
| Compare | diff | Compare definitions between Git references or the working tree. |
| Promote | promote | Preview or apply definition changes between sets. |
Set up #
Create a project#
Requires Node.js 24 or later. Use npx to initialize a project first:
mkdir my-featurevisor-project && cd my-featurevisor-projectnpx @featurevisor/cli@latest initThe @latest tag makes npx fetch the current release, rather than reuse an older version it has cached.
Initialize a specific example from the monorepo:
npx @featurevisor/cli@latest init --example=jsonThe default scaffold uses flat rules without environments. Its all target includes every active feature and global variable without requiring tags. Use init --example=with-environments for shared definitions with staging and production rules. The existing init --example=environments choice uses Sets as release lanes. See Projects for the available setups. Other formats include json and toml. See example projects for more choices.
Use an empty directory. Initialization never overwrites existing files, including a README or .gitignore. Resolve any reported collisions before trying again.
Install the project dependencies:
npm installRun the Featurevisor CLI inside the project:
npx featurevisorFeaturevisor finds featurevisor.config.js by walking up from the current directory. You can run commands from nested directories inside the project without changing back to its root.
To operate on another project, pass either form of the root directory option:
npx featurevisor build --root-directory-path=../my-other-projectnpx featurevisor build --root-directory-path ../my-other-projectHelp#
Use npx featurevisor <command> --help or npx featurevisor help <command> to see the available options for a command. Help remains available outside a project and when a project configuration cannot be loaded.
Built in commands reject unknown options and unexpected positional arguments. This helps catch spelling mistakes before a command does any work. Custom plugins can opt into the same validation by declaring their options.
See Quick start.
Configuration#
View the project configuration:
npx featurevisor configPrint configuration as JSON:
npx featurevisor config --json --prettyVersion#
Print the CLI and package versions:
npx featurevisor version--version and -v print the same output.
Validate #
Lint#
Check if the definition files have any syntax or structural errors:
npx featurevisor lintUse --json for output a script can read, and add --pretty to indent it.
When migrating from v3, run npx featurevisor lint --v3-mutation-order to compare feature mutation results with the old path ordering. This optional check reports changes in mutation results. A difference does not mean a v4 definition is invalid. See the v4 migration guide.
See Linting.
Test#
Run lint before test. Linting validates test specifications, while testing executes their assertions. test does not replace lint validation.
Test features, segments, global variables and scenarios together:
npx featurevisor test| Option | Purpose |
|---|---|
--entity-type=<kind> | Select feature, segment, variable or scenario tests. |
--key-pattern=<regex> | Filter by the key a spec tests, matching case. |
--assertion-pattern=<regex> | Filter assertion descriptions by regular expression. |
--set=<set> | Test one set. |
--target=<target> | Run assertions for these targets, plus untargeted ones. Repeatable. |
--case=<id> | Rerun one exact expanded case within the other filters. |
--json | Print a JSON report. |
--pretty | Indent JSON output. |
--only-failures | Limit human output to failing specs. |
--verbose | Show additional human readable evaluation detail. |
--quiet | Suppress SDK warnings. |
--show-datafile | Print the datafile used by a test. |
--uncovered | List features and global variables without associated authored specs. |
--coverage | Report selections observed during test getter calls. |
--inflate=<number> | Inflate generated test datafiles for development diagnostics. |
--key-pattern matches the feature, segment or global variable a spec tests, or a scenario's key, not the spec's file name. It is case sensitive, as in lint and list. --target does not filter segment specs. The examples use kebab case option names. The CLI also accepts their camel case aliases. Repeatable targets may use --target=web --target=mobile. Built in commands reject unknown options and unsupported --entity-type choices. --only-failures hides successful results in human output while still running the same cases.
See Testing for entity specs, scenarios, checks, reports and exact reruns.
Build #
Build datafiles#
Generate JSON files, one per target and optional environment combination:
npx featurevisor buildPass --target=<target> one or more times to build only those targets. Without it, all targets are built.
Pass --set to build one set:
npx featurevisor build --set=storefrontSee Building datafiles.
Generate code#
Generate TypeScript code from feature definitions:
npx featurevisor generate-code --language typescript --out-dir ./srcSee output in ./src directory. Pass repeatable --tag=<tag> or --target=<target> options to generate the union of features needed by several tags or targets.
See code generation.
Inspect #
Catalog#
Browse your project locally with live updates when definitions change:
npx featurevisor catalogBuild the catalog:
npx featurevisor catalog exportServe the built catalog (defaults to port 3000):
npx featurevisor catalog serveServe it on a specific port:
npx featurevisor catalog serve -p 4000Use --out-dir=<path> to change the output directory, --hash-router for hosts without an HTML fallback, and --test-report=<file> to include saved test results. --pretty-output formats the JSON, while --block-size=<bytes> changes the default 256 KiB block budget. Use --no-assets only when managing the Catalog UI assets separately.
See Catalog options for which commands accept each option and how to host the output.
List#
Choose exactly one entity flag per command. Selecting none or several is an error.
| Entity flag | Lists |
|---|---|
--datafiles | Built files, with their sizes before and after gzip |
--features | Feature definitions |
--segments | Segment definitions |
--variables | Global variable definitions |
--attributes | Attribute definitions |
--schemas | Reusable schemas |
--targets | Target definitions |
--scenarios | Scenarios as written, with their keys and matrices |
--tests | Entity tests and scenarios, normalized for execution |
Use --json for JSON output and --pretty to indent it. Definitions share the filters --description=<pattern>, --key-pattern=<pattern> and --promotable=<true or false>. Tests support the latter two, and take --assertion-pattern=<pattern> for assertion descriptions, --entity-type, --apply-matrix, --case, --execution-metadata and --execution-protocol. --datafiles takes only the output options.
Features, segments, attributes and global variables default to active definitions. Use --archived=true for archived definitions or --archived=false to select active definitions explicitly.
Features and global variables take repeatable --tag=<tag> and --target=<target>. Features also take --variable=<variableKey> and --variation=<variationValue>. To select features with a rule above 0%, or only 0% rules, use --enabled-in=<environment> and --disabled-in=<environment> in a project with environments, and --enabled and --disabled in a project without them. The --with-* and --without-* flags select definitions with or without tests, and features with or without variables or variations. Segments take only the test pair. For features and global variables, test coverage includes owning specs and references in checks or scenarios, including variable operands, feature expectation leaves, children and expanded matrix cases.
npx featurevisor list --features --target=web --without-testsDatafile listings exclude REVISION and hidden files. Directories beginning with dev come first and those beginning with prod last. Terminal sizes use two decimal places and coloured B, kB and mB units. JSON entries contain path, byte size and byte gzipSize.
Test execution input#
Unlike raw --scenarios output, --tests normalizes each scenario into one assertions entry retaining its authored checks, with the public key as its scenario identity. Entity and scenario keys retain directories but omit the terminal .spec. Source filenames stay unchanged.
Native runners should request the versioned envelope:
npx featurevisor list --tests --execution-protocolThis implies JSON, matrix expansion and execution metadata, returning { "kind": "featurevisor.test-execution", "schemaVersion": 1, "tests": [...] }. Runners validate it before building datafiles or evaluating cases and reject unsupported versions. Its version is independent of report and datafile versions. Listings without the protocol option return arrays.
To inspect the expanded array with metadata:
npx featurevisor list \ --tests \ --apply-matrix \ --execution-metadata \ --json \ --pretty--entity-type=<type>selectsfeature,segment,variableorscenariospecs._testrecords the source path, set and entity type. Paths use forward slashes and stay relative to the selected project root, even with an absolute project directory option.- With matrix expansion,
_caserecords an opaque ID, zero based authored assertion and matrix indexes, andmatrixValues. Without an authored matrix,matrixIndexisnulland matrix values are empty. - IDs are assigned before filtering.
--case=<id>implies expansion and fails if the ID does not match within the other filters.
_test and _case are internal execution fields. Do not author them in specs or copy them into context, sticky values or datafiles.
Info#
Shows counts for attributes, segments, features, variables, schemas, targets, test specs and expanded test assertions in the project:
npx featurevisor infoPass --target=<target> one or more times to show counts and datafile sizes for each selected target in each environment. Without it, info shows counts for the whole project.
Find duplicate segments#
Larger projects can contain multiple segments with identical conditions.
Find duplicate segments with:
npx featurevisor find-duplicate-segmentsAdd --authors to identify who worked on the duplicate segments:
npx featurevisor find-duplicate-segments --authorsFind usage#
Learn where entities are used and inspect the dependencies of a global variable.
Choose exactly one feature, segment, attribute, global variable or unused entity query per command. Combining several queries is rejected so no selection is silently ignored.
Add --authors to any find-usage command below to find who worked on the affected entities.
Archived definitions are marked (archived) wherever they appear as users. They are retired, so they never block archiving or deleting what they use.
Segment usage#
npx featurevisor find-usage --segment=netherlandsAttribute usage#
npx featurevisor find-usage --attribute=countryUnused segments#
Lists active segments that no active feature, global variable or segment uses. Archived segments are already retired, so they are left out, and references from archived definitions do not count as use:
npx featurevisor find-usage --unused-segmentsUnused attributes#
Lists active attributes that no active feature, global variable or segment uses, in the same way:
npx featurevisor find-usage --unused-attributesFeature usage#
npx featurevisor find-usage --feature=buyButtonGlobal variable usage#
Shows what a global variable depends on, including other global variables, and which project definitions require it. The reverse lists include indirect requirements. Direct override requirements and authored test checks are listed separately when present. Test check listings identify references. They do not show whether those tests passed. Application code that reads the variable is outside this project query:
npx featurevisor find-usage --variable=supportEmailEvaluate #
Evaluate#
Evaluate a feature against a context to inspect its flag, variation and variable results. These examples use the definitions linked above. For a fresh default scaffold, use --feature=showCookieBanner and a matching country: nl context.
Add --environment=<name> when your project configures environments. Omit it otherwise:
npx featurevisor evaluate \ --feature=buyButton \ --context='{"userId": "user-2", "country": "nl"}'The output includes evaluation details for debugging.
Pass --variable without --feature to inspect a global variable:
npx featurevisor evaluate \ --variable=supportEmail \ --context='{"country": "nl"}'An unknown feature or global variable key exits with code 1, with a spelling suggestion when available. JSON errors use unknown_feature or unknown_variable. A known entity excluded by the selected target still receives the SDK's ordinary missing value result, so --explain can show why it is absent. Disabled features are successful evaluations, not command errors.
Pass --target=<target> one or more times to evaluate independently against the exact datafiles for those targets. With repeated targets and --json, the result is an array containing each target and its evaluations. A single target keeps the regular evaluation object shape.
This resembles SDK diagnostics at debug level, but runs directly against your Featurevisor project without starting your application.
Pass --json to print evaluation details as JSON:
npx featurevisor evaluate \ --feature=buyButton \ --context='{"userId": "user-2", "country": "nl"}' \ --json \ --prettyThe --pretty flag is optional.
Pass --verbose for additional logs:
npx featurevisor evaluate \ --feature=buyButton \ --context='{"userId": "user-2", "country": "nl"}' \ --verboseExplain a result#
Add --explain to describe why the SDK returned a value, using the evaluation details and local project definitions:
npx featurevisor evaluate \ --feature=buyButton \ --context='{"userId":"user-2","country":"nl"}' \ --explainFor a global variable, use --variable instead. This example uses the nested checkout settings definition:
npx featurevisor evaluate \ --variable=checkoutSettings \ --context='{"country":"nl","city":"amsterdam"}' \ --explainThe terminal shows the value, selected rule or override, relevant selectors and a short explanation. It distinguishes an absent value from returned null. The explanation describes the outcome without tracing every execution step. Use --explain --json for full evidence and limitations.
Evaluation builds from your local project without updating allocation state. It does not read deployed datafiles. The explanation identifies the environment, set and target. If a local entity is absent from the datafile, check target selection, exposure and archiving.
Explanation details#
- Evidence is labelled as SDK results, SDK diagnostics, definition information or supplementary CLI probes.
- Global overrides show authored paths and declarations. For ordinary globals, mutations without
continue: trueresolve during building by default. Runtime mutations, including all composed overrides, retain compiled operations. Accumulating overrides show ordered matched paths, including operations that leave values unchanged. Feature variables identify selected sources where available, without a mutation history. - Composition member evidence reads the final SDK result. When a composed override matches,
afterOverrides: truemarks those final member values and the terminal labels them as values after overrides. They are not the original source getter values. The CLI verifies recorded override paths and operations but cannot replay the starting object from runtime values. It makes no extra SDK call to reconstruct that object and does not replay mutations from a fictitious default. - Conditions retain their
and,orandnotgrouping. Explanations show evidence for each root gate leaf and each rule: attribute values, segment matches, feature results and variable values. Missing paths differ fromnull. - Probes may include skipped leaves. They do not trace override requirements or application module changes. Diagnostics record observations and cannot establish a complete dependency tree or prove short circuiting. The original SDK result remains authoritative.
- Explanations can expose configuration and selectors. Review them before sharing.
--verboseadds raw diagnostics to terminal output only.
Structured explanations#
--explain --json --pretty adds explanation. Without --explain, JSON is unchanged. Features contain flag, variation and variables entries. Global variables are described directly. Repeated targets retain target and evaluations, with evaluations.explanation.
Each explanation includes version: 1, mode: "outcome", source, result, summary, evidence and limitations. Absent results have hasValue: false and omit value. Returned nulls have hasValue: true and value: null.
Contradictions between recorded results or selected sources and SDK output exit with code 1. JSON errors use evaluation_explanation_mismatch and details.mismatches. Missing diagnostics are recorded as limitations. These mismatch checks do not rerun selectors or prove intermediate steps.
Benchmarking#
Measure SDK evaluation performance for a feature or variable. Set --n to the number of iterations.
--n and the optional --inflate value must be positive integers. The --context value must be a JSON object. Invalid values are reported before the benchmark begins. --variation and --variable cannot be combined in one benchmark.
--inflate=3 adds synthetic copies so the selected datafile contains three times as many features, segments and global variables. Original definitions are preserved, and generated keys avoid collisions with real keys. Copies retain references to the original dependencies: this increases datafile size and lookup breadth while leaving dependency depth and the number of rules evaluated in one getter unchanged. Use representative definitions and contexts to measure those costs. The same inflation behaviour applies to build and test. Omit the option for production builds.
Pass --target=<target> one or more times to benchmark the same evaluation independently against each selected target datafile. Without it, the complete in-memory datafile is used.
The output includes both the total loop duration and individual evaluation timings:
Total duration: how long all benchmark iterations took togetherMinimum duration: fastest individual evaluationAverage duration: average individual evaluationMaximum duration: slowest individual evaluation
Use the individual evaluation timings when comparing SDK performance. The maximum value can include runtime pauses like garbage collection or process scheduling.
Feature#
The benchmark and distribution examples below use the same buyButton and supportEmail definitions linked above. Include --environment=<name> only if your project configures environments.
To benchmark the SDK's .isEnabled() method against a context:
npx featurevisor benchmark \ --feature=buyButton \ --context='{"userId": "user-2", "country": "nl"}' \ --n=1000Variation#
To benchmark evaluating a feature's variation with the SDK's .getVariation() method:
npx featurevisor benchmark \ --feature=buyButton \ --variation \ --context='{"userId": "user-2", "country": "nl"}' \ --n=1000Variable#
To benchmark evaluating a feature's variable with the SDK's .getVariable() method:
npx featurevisor benchmark \ --feature=buyButton \ --variable=label \ --context='{"userId": "user-2", "country": "nl"}' \ --n=1000To benchmark a global variable, omit --feature:
npx featurevisor benchmark \ --variable=supportEmail \ --context='{"country": "nl"}' \ --n=1000Assess distribution#
Simulate many users with a supplied context to inspect a feature's rollout and variation distribution:
npx featurevisor assess-distribution \ --feature=buyButton \ --context='{"country": "nl"}' \ --populate-uuid=userId \ --n=1000For 1,000 Dutch users, buyButton comes out close to its 50/50 split:
Flag evaluations • enabled: 1,000 100.00% • disabled: 0 0.00%Variation evaluations • treatment: 504 50.40% • control: 496 49.60%Each run draws new IDs, so the counts vary a little. Use it to check a split before an experiment starts, or after changing its weights.
Set --n to the number of iterations. Use --populate-uuid to simulate a different user in each iteration.
The iteration count must be a positive integer, and --context must contain a JSON object.
Options:
--environment: required when the project configures environments, otherwise omitted--feature: the feature key--context: the common context object in stringified form--populate-uuid: attribute key that should be populated with a new UUID, and merged with provided context.- Pass multiple attributes to populate each one:
--populate-uuid=userId --populate-uuid=deviceId
- Pass multiple attributes to populate each one:
--n: the number of iterations to run the assessment for- The higher the number, the more accurate the distribution will be
--target: assess the exact target datafile. Repeat it to assess several targets independently--verbose: print the merged context for better debugging
The command runs locally in memory without modifying project files. Use the results to check how users are distributed.
Compare #
Compare changes#
Review changes to your Featurevisor definitions in a readable form:
npx featurevisor diffThe comparison is selected automatically:
- With uncommitted changes, compare the last commit on the current branch with the working tree. This takes precedence on every branch, including the primary branch.
- On a clean primary branch, such as
mainormaster, there are no changes to show. - On another clean branch, compare the primary branch with the current commit.
Staged changes, unstaged changes, deleted files and untracked definitions are included. Ignored untracked files are excluded. The comparison uses the final files on disk, including any changes made after staging. Changes anywhere in the Git working tree select the uncommitted comparison, but only the current Featurevisor project's definitions are reported.
Choose Git references to override these defaults:
npx featurevisor diff --from=main --to=HEADnpx featurevisor diff --from=HEAD --to=working-treeReferences can be branches, tags or commit hashes. working-tree is a reserved endpoint name for the current files on disk. Passing only --from compares that reference with the working tree. Passing only --to compares HEAD with that reference. Commit comparisons use the two commit contents directly, not their merge base.
For example, a changed global variable appears as:
Comparing HEAD → working-tree~ variable supportEmail Default value: "[email protected]" → "[email protected]"0 added, 1 changed, 0 removedThe report covers features, global variables, segments, attributes, schemas, targets and test specifications. It ignores comments, formatting and object property order.
Rules and overrides are matched by their keys, and variations by their values, so inserting a rule does not make every rule after it appear updated. The report names each added, updated or removed item within its parent, and its environment when there is one. Raising checkout from 25% to 50% reads:
~ feature checkout Rules Rule "everyone" updated Rollout percentage: 25 → 50Nested global overrides retain their parent hierarchy. Feature variable overrides are grouped under their rule or variation and variable key. A change in the relative order of existing rules or overrides is reported separately, because order affects evaluation. Added items show their new position, starting at one. Lists with missing or duplicate identities are compared by position instead. Arrays inside variable values are compared as values, even if their objects have a key property.
A renamed definition, rule key or override key appears as a removal and an addition.
In projects using sets, all sets present in either version are compared. Use --set to select one:
npx featurevisor diff --set=productionnpx featurevisor diff --from=main --to=HEAD --json --prettyJSON output contains from, to, the selection reason, warnings, a summary and entity changes. Each entity includes its key, type, file, optional set, positional field changes with before and after values, and readable details grouped by authored identities. Field changes retain JSON Pointer syntax with array positions starting at zero. Readable details use positions starting at one. A successful comparison exits with status 0, whether or not it finds changes. Invalid references, unreadable definitions and unresolved working tree conflicts exit with status 1.
The command reads local Git history without fetching, checking out files, building datafiles or changing build state. Primary branch discovery uses the upstream or remote default branch when known, then local main, master or the configured Git default branch, with remote main or master as a fallback. An existing local primary branch takes precedence over its remote tracking version. Update your local Git references yourself when you want a newer baseline, or pass explicit references.
The comparison shows definition changes. It does not predict which users will receive different evaluations. Both versions use the current project's parser and directory configuration. Changes to featurevisor.config.js are reported, with a warning when the compared configuration differs from the current configuration. Historical configuration is not executed. Review configuration changes and directory moves with git diff, since files outside the current directory layout cannot be classified. The filesystem datasource adapter and an existing Git commit are required.
Promote #
Promote between sets#
Use promotions to preview and apply changes from one set to another.
Preview what would be copied:
npx featurevisor promote --from=dev --to=stagingApply the promotion to write destination files:
npx featurevisor promote --from=dev --to=staging --applySee Promotions.
Error output#
Command argument, configuration and execution errors normally print to standard error and exit with a nonzero code.
For commands that accept --json, these errors use a structured object on standard error:
{ "error": { "code": "unknown_command", "message": "Unknown command \"frobnicate\".", "details": { "command": "frobnicate" } }}The code property is stable and meant to be matched against, while message is written for humans. The details object carries additional context when there is any, and is an empty object otherwise. Add --pretty to indent the output.
Error codes#
| Code | When it occurs | Recommended action |
|---|---|---|
invalid_cli_arguments | An option is unknown, malformed or followed by an unexpected argument. | Check the command's --help output and correct the arguments. |
unknown_command | The command name does not exist. | Run npx featurevisor help and correct the command name. |
duplicate_cli_command | A plugin registers an existing command name. | Rename or remove the conflicting plugin command. |
project_not_found | No project configuration is found. | Run inside the project or pass --root-directory-path. |
invalid_project_configuration | The configuration cannot be loaded or validated. | Fix the reported configuration error and retry. |
unknown_feature | evaluate cannot find the feature in the project. | Correct the feature key or add its definition. |
unknown_variable | evaluate cannot find the global variable in the project. | Correct the variable key or add its definition. |
variable_not_found | find-usage cannot find the selected global variable. | Check the key with list --variables. |
feature_not_found | find-usage cannot find the selected feature. | Check the key with list --features. |
segment_not_found | find-usage cannot find the selected segment. | Check the key with list --segments. Namespaced keys use the configured separator. |
attribute_not_found | find-usage cannot find the selected attribute. | Check the key with list --attributes. |
invalid_saved_allocation | Saved variation allocation state is invalid. details.stateFile identifies the allocation file when available. | Restore valid state or deliberately start a new rule allocation. See State files. |
invalid_environment | The selected environment is unknown or the project has no environments. | Use a configured environment, or the options for projects without environments, such as omitting --environment or using --enabled. |
missing_environment | A command needs one datafile from a project with environments. | Pass --environment=<name>. |
invalid_set | The selected set is unknown, or the project does not configure sets. | Use a listed set, or omit --set in a project without sets. |
missing_set | JSON output from a project with sets needs one set. | Pass --set=<name>. |
no_sets | A project configures sets, but its sets directory has none. | Create a set directory, or turn sets off. |
invalid_evaluation_selection | evaluate selects both a feature and a global variable, or neither. | Pass exactly one of --feature or --variable. |
invalid_list_selection | list selects multiple entity kinds, or none. | Pass exactly one entity selector, such as --features. |
invalid_find_usage_selection | find-usage has no unique entity selection. | Choose exactly one supported entity selector. |
incompatible_cli_options | An option does not apply to the selected entity or output. | Remove the option or choose a compatible selection from --help. |
conflicting_cli_options | Two options request incompatible behaviour. | Keep only one of the conflicting options named in the error. |
missing_cli_option | A required option is absent. | Supply the option named in the error. |
invalid_json | An option contains malformed JSON. | Use valid JSON and quote the complete argument for your shell. |
invalid_json_type | An option requires a JSON object but receives another type. | Pass an object such as '{}', not an array or null. |
invalid_number | An option requires a positive integer. | Pass a whole number greater than zero. |
invalid_regular_expression | A filter contains an invalid regular expression. | Correct and quote the expression. |
test_case_not_found | No expanded case matches --case within the selected filters. | List current cases with list --tests --apply-matrix --json and reuse a matching ID. |
invalid_test_case | --case does not contain one nonempty case ID. | Pass one complete case ID. |
removed_test_field | A feature spec still uses sticky when specs are listed or run. | Rename it to stickyFeatures, then run lint. |
evaluation_explanation_mismatch | An explanation does not match the evaluated result. | Retry with the same definitions and context. Report a reproducible mismatch with the CLI version. |
diff_error | Git references or changes cannot be compared. | Check the reported Git error, references and available history. |
unexpected_error | The command encounters another failure. | Inspect the message and retry with --verbose. Report a reproducible failure with the CLI version. |
Lint findings and test reports use different JSON formats on standard output. Lint reports contain an errors array. Test reports retain their report shape for failed assertions and preparation errors, including invalid filters or inflation values. Check the exit status and the report's errors rather than assuming every failure uses the stderr envelope. See lint issue codes and test reports.

