Skip to content

feat: add apify actors doctor for local Actor diagnostics - #1367

Open
kuntal1461 wants to merge 1 commit into
apify:masterfrom
kuntal1461:feat/actors-doctor
Open

feat: add apify actors doctor for local Actor diagnostics#1367
kuntal1461 wants to merge 1 commit into
apify:masterfrom
kuntal1461:feat/actors-doctor

Conversation

@kuntal1461

Copy link
Copy Markdown
Contributor

Closes #1366

Summary

Adds apify actors doctor — an offline, read-only diagnostic command that checks the local Actor project before deployment. The intended workflow is:

develop → apify actors doctor → fix local issues → apify actors push

Doctor catches locally representable configuration and schema problems (malformed config, missing schema references, invalid schema structure) before a push is attempted. Passing doctor does not guarantee a successful cloud build — it validates only what is locally checkable.

Why this helps developers

  • Faster feedback loop — locally detectable configuration issues can be surfaced before deployment-related workflows
  • Aggregated diagnostics — independent failures (invalid input schema, missing output schema, invalid dataset schema) are all reported in a single run rather than stopping at the first error
  • Clear error taxonomy — missing reference / malformed JSON / structurally invalid schema produce distinct diagnostics
  • No credentials required — safe to run in a fresh clone, CI, or before login
  • Non-destructive — never modifies the Actor project

Architecture

         Canonical Apify validators
                    │
       ┌────────────┼─────────────┐
       ▼            ▼             ▼
 Actor schema   Input schema  Storage schemas
  validator      validator      validators
       │            │             │
       └────────────┼─────────────┘
                    ▼
           Shared schema readers
           (src/lib/input_schema.ts)
                    │
          ┌─────────┴──────────┐
          ▼                    ▼
  validate-schema         actors doctor
                               │
                               ▼
                        diagnostics list
                               │
                               ▼
                          CLI rendering

Doctor owns orchestration and presentation; canonical Apify validators own the rules. This avoids a second ruleset that could drift from the Actor specification.

Why this architecture

The central design constraint is that doctor must not duplicate validation rules. Every check delegates to an existing canonical validator:

  • getActorSchemaValidator() (@apify/json_schemas) — actor.json structure
  • validateInputSchema() (@apify/input_schema) — input schema validity
  • getDatasetSchemaValidator(), getOutputSchemaValidator(), getKeyValueStoreSchemaValidator() (@apify/json_schemas) — storage schema validity

Doctor's own code handles: discovery, parsing, short-circuit logic (don't crash on null actor.json), error aggregation, and terminal rendering.

Trade-offs

Separate command instead of changing actors push

  • New opt-in command; push behavior is unchanged
  • Low regression risk; maintainers can evaluate independently
  • Trade-off: developers must run doctor explicitly

Offline instead of cloud simulation

  • No network calls, no auth, no Docker, no Actor execution
  • Fast and deterministic; works offline and in CI
  • Trade-off: doctor cannot validate what the cloud build will accept

Canonical checks only, no heuristics

  • Does not check package.json, lock files, Node version, Python environment, or Docker
  • Apify Actors support multiple languages and build strategies — heuristic warnings would produce false positives and erode developer trust
  • Trade-off: some categories of problem are intentionally out of scope

Shared helper changes instead of doctor-only parsing

  • Correctness improvements to input_schema.ts and validate-schema.ts benefit all consumers
  • Trade-off: broader regression surface — mitigated by testing all known callers

Simple flat check list instead of a plugin/registry framework

  • V1 scope is small; premature abstraction would complicate review with no immediate benefit
  • Trade-off: if the command grows substantially, checks may need extraction later

Impact on existing commands

Command Impact Evidence
apify actors push No behavior change push tests: 11/11 passed
apify validate-schema Intentional improvement: now recognises inputSchema/outputSchema aliases and storages.datasets plural form validate-schema tests: 10/10 passed
apify actor generate-schema-types Intentional improvement: benefits from canonical input/output schema alias resolution; storages.datasets type generation remains out of scope generate-schema-types tests: 60/60 passed
apify init No behavior change init tests: 4/4 passed
apify run No behavior change expected from shared input-reader changes Real local smoke test passed; repository run tests could not complete due to unrelated environment/setup prerequisites

Shared improvements

src/lib/input_schema.ts now consistently handles:

  • inputSchema as an alias for input (canonical actor schema supports both)
  • outputSchema as an alias for output
  • storages.datasets (plural, named entries) alongside storages.dataset (singular)
  • Per-entry error classification for dataset schemas: ref-missing vs parse-failed are reported as distinct diagnostics

These forms are part of the canonical Actor schema; the previous shared reader code did not handle them consistently. validate-schema now uses these improved readers, so it benefits from the same correctness fix.

Safety characteristics

  • No network calls
  • No authentication required
  • No file mutation — config is never migrated, rewritten, or touched
  • No new external dependencies
  • Terminal output is sanitized for ASCII control characters (strip chars 0x00–0x1F, 0x7F) before rendering, to prevent escape-sequence injection from project-controlled values such as actor names or file paths in actor.json
  • Non-object actor.json root values (null, [], strings, numbers, booleans) produce a clean canonical schema error and do not crash

Testing

Automated tests

Suite Result
actors doctor 52 / 52 passed
validate-schema 10 / 10 passed
actor generate-schema-types 60 / 60 passed
apify push 11 / 11 passed
apify init 4 / 4 passed
Full local suite 540 passed, 2 pre-existing Python env failures (unrelated to this change)
pnpm run lint Passed
pnpm exec tsc --noEmit Passed
pnpm run format Passed

Real CLI testing

The built local entrypoint (dist/apify.js actors doctor) was exercised against real temporary Actor projects covering:

  • Valid Actor → exit 0, "No issues found."
  • Missing .actor/actor.json → clean error diagnostic
  • Malformed actor.json (invalid JSON) → parse error diagnostic
  • null / [] / string / number / boolean actor.json → canonical schema error, no crash
  • Invalid Actor name → name validation error
  • input and inputSchema field forms
  • output and outputSchema field forms
  • storages.dataset and storages.datasets with multiple named entries
  • storages.keyValueStore
  • Missing referenced files → ref-missing diagnostic
  • Malformed referenced JSON → parse-failed diagnostic
  • Structurally invalid schemas → invalid diagnostic
  • Multiple simultaneous independent errors (all aggregated, not stopped at first)
  • Legacy apify.json with and without actor.json present
  • Terminal control character in actor name (ESC byte) → sanitized output, raw ESC not printed
  • No project files mutated after any run

Backward compatibility

  • actors push behavior is unchanged
  • No existing command removed or renamed
  • actors doctor is strictly additive
  • No new external npm dependency
  • No network requirement added
  • No project mutation in any execution path

Known limitations / follow-ups

The following are pre-existing concerns intentionally excluded from this PR to keep it focused:

  • actor generate-schema-types does not yet generate types from storages.datasets entries (plural form) — separate concern
  • The actor-name validation error message mentions a 30-character maximum while ACTOR_NAME.MAX_LENGTH is 63 — pre-existing message inconsistency
  • Repository run test suite could not complete locally due to unrelated environment/setup prerequisites (TEST_USER_TOKEN, template network fetch); isolated from this feature

Adds apify actors doctor — an offline, read-only pre-flight command
that checks the local Actor project before deployment. Reuses canonical
Apify validators from @apify/json_schemas and @apify/input_schema.

Checks: actor.json presence, JSON parsing, canonical Actor schema,
Actor name constraints, and all referenced schema files (input,
output, dataset, KVS), including both singular and plural/alias forms.

Also improves shared schema resolution in src/lib/input_schema.ts and
src/commands/validate-schema.ts to recognise inputSchema/outputSchema
aliases and storages.datasets plural form consistently across commands.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Add apify actors doctor for local Actor project diagnostics

2 participants