Agent Skill · Specmatic

fix-openapi-spec

Use when asked to identify and fix errors in an OpenAPI specification that are preventing it from running as mock or test

Provider: Specmatic Path in repo: skills/fix-openapi-spec/SKILL.md

Skill body

Fix OpenAPI Spec

Use this skill when the task is to diagnose an OpenAPI specification that is preventing it from running as mock or test.

Reading Rule

Canonical Paths

Use these exact paths and file names everywhere in this workflow.

Script Location Rule

Workflow State Machine

Phase 1 -> Phase 2 -> Phase 3 -> Phase 4 validation -> STOP for user approval -> Phase 4 fixes only if explicitly approved

Docker Execution Rule

Script Execution Rule

Working area

Ignore any old test files or log files that existed before this conversation. You’ll work with the output of the relevant commands as per the workflow state machine.

Phase 1: Setup

  1. Create a copy of the input spec path for edits named <spec-name>-updated.<ext> in the same directory as the source spec.
    • Note: Always edit the -updated copy. Do not update or fix the original spec.
  2. Create a single append-only actions log file named fix-log-<spec-name>-<current-date>.md in the spec directory, with the following initial content: ``` # Actions log for
### Phase 2: Auto-fix obscure errors

1. Run the loop test script against the editable copy. If you run into permissions issues and even after the Docker rule is run it doesn't get resolved, go to phase 4.
2. Immediately after the loop test ends, append a structured entry to `fix-log-<spec-name>-<current-date>.md` with this format:

## **Timestamp**: <timestamp> **Action**: Loop test run **Result**: [pass|fail] - <brief description="" of="" the="" result=""></brief></timestamp>

3. If the loop test passes, go to step 5, the final check. All failed tests are considered "must-fix" errors.
4. If the loop test fails, attempt to fix one of the errors following the guidelines for addressing errors, and then go back to step 1.
5. If any must-fix errors remain to be addressed, go back to step 1 and repeat the process until all must-fix errors have been addressed.
6. Final check: once all the tests are passing, go back to step one and run the loop test again to make sure that there are no errors left.

Guidelines for addressing errors:
- Classify every failure before moving on:
  - `Spec Issue`: the run points to a concrete schema, example, enum, `$ref`, `required`, or constraint defect in the spec.
  - `Specmatic Bug`: the error is unclear (does not identify a concrete spec defect or provide enough information to point directly to where the issue is), or if it appears that Specmatic cannot handle a value / feature in the spec that is perfectly legimiate (e.g. valid regex syntax, valid OpenAPI syntax, etc)
  - Treat any opaque error as a `Specmatic Bug`. "Opaque" means the message does not identify a concrete spec defect or does not provide enough information to fix the spec confidently.
  - If relaxing or removing a valid constraint is used to make the workflow pass, log it as a `Specmatic Bug`.
  - A status mismatch is not opaque merely because the final summary only shows `R0002`. Before classifying it as `Specmatic Bug`, inspect the raw temp test log around the full request/response transcript. Look both above and below the failed scenario summary. Only classify as opaque if no response body or adjacent transcript contains a concrete contract path or rule violation.
  - If Specmatic-generated traffic fails against the same specification, classify it as `Specmatic Bug` unless the failing constraint is itself invalid OpenAPI, invalid syntax, or demonstrably conflicts with another schema rule such as enum/example values.


- If the issue is classified as a `Specmatic Bug`, log it immediately when first observed in `fix-log-<spec-name>-<current-date>.md`, using this format:

## **Timestamp**: <timestamp> **Action**: Issue Classification **Error**: <error message="" that="" prompted="" this="" bug="" classification=""> **Classification**: Specmatic Bug **Reason**: <why this="" is="" considered="" a="" Specmatic="" Bug="" instead="" of="" concrete="" spec="" defect=""> **Logs**: <log snippet="" showing="" the="" issue="" that="" prompted="" fix=""></log></why></error></timestamp>


- If the issue is classified as a `Spec Issue`, log it immediately when first observed in `fix-log-<spec-name>-<current-date>.md`, using this format:

## **Timestamp**: <timestamp> **Action**: Issue Classification **Error**: <error message="" that="" prompted="" this="" bug="" classification=""> **Classification**: Spec Issue **Reason**: <why this="" is="" considered="" a="" Spec="" Issue="" instead="" of="" Specmatic="" Bug=""> **Logs**: <log snippet="" showing="" the="" issue="" that="" prompted="" fix=""></log></why></error></timestamp>


- Do not wait for the bug to be resolved before logging it.
- Form a hypothesis about the cause of the error, and whether there is an allowed fix which you have not yet tried that will resolve it. Even if the error seems unclear or opaque, form a hypothesis anyway, make your best guess, based on the error message, field names, and schema context.
- If allowed fixes are available to be tried as per the "Allowed fixes" section,
  - attempt the fixes in order of preference as outlined,
  - Immediately after applying a fix, append a structured entry to `fix-log-<spec-name>-<current-date>.md` with the format:

## Fix: <summary of the fix> Timestamp: **Action**: Fix applied **Fix**: **Reason**: **Logs**:

  - Then go back to Step 1 of this phase and run the loop test again to see if the fix resolved the issue.

- However if there are no more allowed fixes left to try and the issue remains unresolved, consider the issue addressed and log a "Specmatic Bug" entry in the following format:

## Unfixable: <summary of the bug> Timestamp: **Action**: Dropping issue as unfixable **Classification**: Specmatic Bug **Reason**: **Logs**:

- When logging a failed loop run, include the most specific inner contract error found in the response body. Do not log only the outer status mismatch if the response body contains a deeper rule violation.

  For example, log:
  `REQUEST.QUERY.path.to.something <error>` or `RESPONSE.BODY.path.to.something <error>` or

  instead of:
  `confirm-payment-source returned 400 instead of 200`.

### Phase 3: Report on auto-fix phase

Prepare a console report for the user. Do not mention mechanics such as test execution details, mock startup details, or pass/fail runtime chatter.

1. Read fix log at `fix-log-<spec-name>-<current-date>.md` in order to identify Specmatic bugs and applied fixes. Do not depend on memory.
2. If it contains `Classification**: Specmatic Bug`, the final response MUST include a `Specmatic bugs:` section.
3. If it contains `Fix applied`, the final response MUST include a `Fixes applied:` section.
4. Specmatic bugs section should be followed by the Fixes applied section if both exist, else just the one that exists should be printed.
5. If any Specmatic bugs exist, the final response MUST say to send:
    - original spec
    - updated spec
    - fix log
6. Do not substitute validation/test summaries for these sections.

The format for the Specmatic bugs section is:

Specmatic bugs:

Please send the following files to the Specmatic team for analysis:

The format for the list of fixes applied is:

Fixes applied:
- <item fixed>: <brief description of the fix>
- <item fixed>: <brief description of the fix>

Phase 4: Address load time errors and warnings

  1. Run the validate command on the <spec-name>-updated.<ext> spec.
  2. If there are no errors or warnings, report to the user that the spec is now valid and can be used for testing and mocking with Specmatic, and end the process.
  3. If there are errors or warnings, list out each issue in it’s own section, including: issue path if provided, issue description, a reasonable option you can come up with for fixing it, and if the fix is to change or add something then show a spec snippet of the fix. Then ask the user which of the spec defects on the -updated copy they want your help to address, how they want to address it, before applying any fix. Do NOT fix any errors or warnings automatically. Do not infer approval to fix from the original request, or from prior sessions. Only proceed if the next user message explicitly approves fixing any issues or requests specific fixes.
  4. For each load-time error or warning that the users wants to address:
    • Classify and log the error following the same classification and logging contract as in Phase 2.
  5. Apply allowed fixes to the -updated copy based on the error messages and classification, following the same guidelines for allowed fixes as in Phase 2.
  6. Repeat this phase until all actionable load-time errors are addressed.
  7. If you conclude that an issue cannot be fixed using allowed fixes, log it as a “Specmatic Bug” following the same contract as in Phase 2, consider it addressed.

Disallowed fixes

The following changes are not allowed:

Allowed fixes

Guidelines for fixing constraints and examples:

When a scenario fails with HTTP status mismatch

If a loop test reports R0002: HTTP status mismatch, do not classify it as opaque until you inspect the request/response transcript for that same failed scenario.

Specmatic often prints the detailed contract failure inside the mock response body, before the final Unsuccessful Scenarios summary. Search upward from the failed scenario or from Specification expected status ... but response contained status 400 for the nearest preceding:

If the response body contains a concrete >> REQUEST... or >> RESPONSE... path, treat that as the primary failure, not the outer R0002 status mismatch.

Example:

Logging Contract (Mandatory)