Troubleshooting
Preview Feature: CLI AI Automation is a preview feature. If you encounter any issues, please report them at support.skipper18.com.
This page covers common issues you may encounter when using the Skipper CLI, how to interpret error codes, and techniques for diagnosing problems.
Error Codes Reference
Every error returned by the CLI includes a machine-readable code field in the JSON envelope. The table below lists all possible error codes, their associated exit codes, and recommended resolutions.
| Code | Exit Code | Meaning | Resolution |
|---|---|---|---|
UNKNOWN_VERB | 2 | The specified CLI verb does not exist. | Run -cli-help to see the list of available verbs. |
MULTIPLE_VERBS | 2 | More than one CLI verb was specified. | Use only one -cli-* flag per invocation. |
MISSING_REQUIRED | 2 | A required argument is missing. | Check the verb signature in -cli-help and supply all required arguments. |
INVALID_ARG_VALUE | 2 | An argument has an invalid value. | Review the argument constraints in the CLI Reference. |
MALFORMED_INPUT_FILE | 2 | The input file (e.g., ops.json) has invalid syntax. | Validate JSON syntax with jq . ops.json and fix any parse errors. |
PROJECT_LOAD_FAILED | 1 | The project file could not be loaded. | Verify the file path is correct, the file exists, and it is a valid .skipper project. |
IO_ERROR | 1 | A file system read/write operation failed. | Check file permissions, disk space, and that output paths are writable. |
EXPORT_FAILED | 1 | Code generation or export encountered an error. | Check the export path, framework configuration, and project validity. Run -cli-validate first. |
VALIDATION_FAILED | 1 | The project contains validation errors. | Review the data field for details on each validation issue and fix them in the project. |
UNKNOWN_FRAMEWORK | 1 | The specified ORM framework is not recognized. | Check available frameworks in your Skipper configuration. Common values: Doctrine2, Laravel, Symfony. |
MIGRATIONS_DISABLED | 1 | Migration operations are not enabled for this project. | Enable migrations in the project settings before using migration-related verbs. |
MIGRATIONS_OUT_OF_SYNC | 1 | Project has changes not recorded in the migration log. | Run -cli-create-migration to generate a migration for pending changes. |
DB_CONNECTION_FAILED | 1 | Could not connect to the database. | Verify database host, port, credentials, and that the server is running. |
DB_IMPORT_FAILED | 1 | Database import encountered an error. | Check database connectivity and ensure the target schema is accessible. |
VIEWER_LICENSE | 1 | CLI requires a paid license; Viewer (free) is not sufficient. | Upgrade to a paid Skipper license. |
MAINTENANCE_EXPIRED | 1 | License maintenance has expired. | Renew your maintenance subscription at skipper18.com. |
INVALID_OP | 1 | An operation in the ops.json file is invalid. | Review the operation type and its required fields against the schema format. |
INVALID_MERGE_INPUT | 1 | Merge input is invalid. Check error.details.root_cause_code for cause. | Review the merge JSON structure and referenced entities. |
OBJECT_NOT_FOUND | 1 | The referenced entity, field, or association was not found. | Check the object name, including namespace prefix. Use -cli-schema-summary to list available objects. |
NOT_IMPLEMENTED | 1 | The requested operation is not yet implemented. | This feature is planned for a future release. Check the CLI Reference for currently supported verbs. |
INTERNAL_ERROR | 3 | An unexpected internal error occurred. | Re-run with -verbose and report the issue to support. |
Validation Codes
When running -cli-validate, the response may include validation issues with their own codes. Warnings (exit 0) do not fail the command; errors (exit 1) cause VALIDATION_FAILED.
| Code | Exit Code | Severity | Meaning |
|---|---|---|---|
NULLABLE_PK | 0 | warning | Primary key field is nullable -- PK should be NOT NULL. |
MISSING_PK | 0 | warning | Entity has no primary key field. |
EMPTY_ENTITY | 0 | warning | Entity has no fields defined. |
MISSING_FIELD_TYPE | 1 | error | Field has no data type set. |
BROKEN_ASSOCIATION | 1 | error | Association references a missing entity or field. |
INVALID_ENUM_VALUE | 1 | error | ORM attribute has an invalid enum value. |
INVALID_FIELD_TYPE | 1 | error | Field data type is not recognized by the project's framework. |
MIGRATIONS_OUT_OF_SYNC | 1 | error | Project has changes not recorded in the migration log. |
Common Issues
License not loaded
If you receive a VIEWER_LICENSE or MAINTENANCE_EXPIRED error, verify the following:
Your license file is present in the expected location. On Windows, Skipper stores license data in the registry and in the application data directory.
Your maintenance subscription is active. CLI automation requires current maintenance. Check your status at skipper18.com.
If running in a CI/CD environment, ensure the license has been activated on the build machine. Skipper needs to have been launched at least once with the GUI to register the license before CLI mode can use it.
Viewer License Limitations
Viewer licenses can only use read-only CLI verbs: help, validate, export, schema-summary, compare, and export-diagram. Write operations (apply-patch, apply-merge, create-project, import-project, import-database, create-migration) require a full license.
Entity not found
The OBJECT_NOT_FOUND error often occurs because of namespace prefix mismatches. Skipper stores fully qualified entity names including the namespace.
If your entity is
App\Entity\User, you must reference it as\App\Entity\User(with leading backslash) in CLI arguments.Run
-cli-schema-summaryto see the exact names Skipper uses internally.Entity names are case-sensitive.
# Wrong - may fail with OBJECT_NOT_FOUND
Skipper.exe -cli-entity-detail project.skipper Entity\User
# Correct - use the fully qualified name
Skipper.exe -cli-entity-detail project.skipper \App\Entity\UserEntity Not Found with Short Name
If two entities share the same short name in different modules (e.g. \App\Entity\User and \Admin\Entity\User), Skipper cannot disambiguate by short name alone. Use the fully qualified name (FQN) to identify the correct entity:
# Ambiguous - two "User" entities exist
Skipper.exe -cli-entity-detail project.skipper User
# Unambiguous - use FQN
Skipper.exe -cli-entity-detail project.skipper \App\Entity\UserAttribute type not found
When working with ORM attributes, the attribute path must match your framework configuration exactly.
Each ORM framework defines its own set of valid attribute types and paths.
Check your framework configuration file (e.g.,
Doctrine2.skipper.cfg.xml) for the list of supported attributes.Ensure your project is configured for the correct framework. Mismatched framework settings will cause attribute lookups to fail.
ORM Attribute Path Format
When setting ORM attributes via patch operations, use the plain attribute name without any prefix. The orm: prefix is auto-stripped by Skipper, so both forms are equivalent:
// Correct - plain attribute name
{ "path": "table", "value": "customers" }
// Also works - orm: prefix is auto-stripped
{ "path": "orm:table", "value": "customers" }
// Recommended: always use the plain form
{ "path": "repository-class", "value": "App\Repository\UserRepository" }Duplicate Field Name
The add_field patch operation silently skips if a field with the same name already exists on the entity. No error is returned -- the existing field is left unchanged. If you need to modify an existing field, use update_field instead.
JSON Escape Auto-Correction
AI tools frequently produce incorrectly escaped namespace strings. For example, an AI might write \App\Test (with single backslashes) instead of \\App\\Test (properly escaped). Skipper auto-corrects invalid escape sequences in namespace and class-name values:
\App\Testis auto-corrected to\\App\\Test(invalid escape sequences are treated as literal backslashes)./App/Test(forward slashes) is also auto-converted to\\App\\Test.This auto-correction applies to entity names, namespace values, and class references in patch and merge operations.
While auto-correction handles common cases, it is still recommended to use properly escaped strings in your JSON input for clarity.
Cannot delete file skipper.db
Skipper uses a SQLite database (skipper.db) for internal state. If the CLI reports that it cannot delete or access this file:
Another Skipper instance is running. Close any open Skipper GUI windows or other CLI processes that may be using the same project.
On Windows, use Task Manager to check for lingering
Skipper.exeprocesses.If the file is locked by a crashed process, you can safely delete
skipper.dbmanually. Skipper will recreate it on the next run.
MALFORMED_INPUT_FILE
This error indicates that the input JSON file (typically ops.json) has a syntax error and cannot be parsed.
Validate the file with a JSON linter before passing it to Skipper:
# Validate JSON syntax
jq . ops.json
# Common issues:
# - Trailing commas after the last element in arrays/objects
# - Unescaped backslashes in strings (use \\ for literal backslash)
# - Single quotes instead of double quotes
# - Missing closing bracketsIf the file was generated by an AI assistant, ask it to output raw JSON without markdown formatting (no ```json wrappers).
Debugging
When a CLI command fails or produces unexpected results, use these techniques to diagnose the issue:
Verbose output
Add the -verbose flag to any CLI command to get detailed diagnostic output on stderr. This includes project loading steps, framework resolution, entity lookups, and timing information.
Skipper.exe -cli-validate project.skipper -verboseReading stderr
The JSON envelope goes to stdout, while diagnostic messages go to stderr. To capture both separately:
# Capture JSON to file, see diagnostics in terminal
Skipper.exe -cli-validate project.skipper > result.json
# Capture both separately
Skipper.exe -cli-validate project.skipper > result.json 2> diagnostics.log
# View diagnostics after the run
cat diagnostics.logPersistent log file
For CI/CD pipelines or automated runs where stderr may not be captured, use -log-file to write all diagnostic output to a persistent file:
Skipper.exe -cli-export project.skipper -log-file /var/log/skipper-cli.logEnvelope Error Structure
When a CLI verb fails, the JSON envelope contains an error object with structured information. Here is how to parse it programmatically:
{
"status": "error",
"command": "entity-detail",
"error": {
"code": "OBJECT_NOT_FOUND",
"message": "Entity '\\User' not found in project.",
"hint": "Use the fully qualified name including namespace, e.g. '\\App\\Entity\\User'. Run -cli-schema-summary to list all entities."
},
"warnings": [
"Project contains 3 unresolved association targets."
],
"meta": {
"duration_ms": 890,
"skipper_version": "3.3.8.1844",
"schema_version": "3",
"started_at": "2026-04-30T10:20:45Z"
}
}To handle errors in a script, check the status field first, then read the error.code for programmatic branching:
# Parse the result with jq
RESULT=$(Skipper.exe -cli-validate project.skipper 2>/dev/null)
STATUS=$(echo "$RESULT" | jq -r '.status')
if [ "$STATUS" = "error" ]; then
CODE=$(echo "$RESULT" | jq -r '.error.code')
MESSAGE=$(echo "$RESULT" | jq -r '.error.message')
HINT=$(echo "$RESULT" | jq -r '.error.hint // empty')
echo "Error [$CODE]: $MESSAGE"
[ -n "$HINT" ] && echo "Hint: $HINT"
exit 1
fi
echo "Validation passed."
echo "$RESULT" | jq '.data'Key points for error handling:
status is always present and is either
"ok"or"error".error.code is a stable, machine-readable identifier. Use it for programmatic decisions (retries, fallbacks, reporting).
error.message is a human-readable description of what went wrong.
error.hint is optional and provides actionable guidance when available.
warnings may be present even on success. Always check warnings for potential issues that did not block execution.
For the complete list of CLI verbs and their parameters, see the CLI Reference. For general setup information, see the Introduction.