Document Purpose: Quick reference for diagnosing and fixing issues in the multi-version SDK generation, publishing, and release workflows.
Last Updated: February 18, 2026
Audience: Developers debugging workflow failures
Check in this order:
- Is the OpenAPI spec file accessible?
- Does the config file exist for that API version?
- Are there syntax errors in the config file?
Check in this order:
- Did the commit reach master successfully?
- Is
NPM_AUTH_TOKENsecret valid? - Did the path filter (
v20111101/**, etc.) match the changes?
Check in this order:
- Did publish step complete successfully?
- Does the release tag already exist?
- Does
GITHUB_TOKENhave release creation permissions?
The generate.yml and openapi-generate-and-push.yml workflows run configuration validation before SDK generation. If validation fails, the workflow stops immediately to prevent invalid configurations from generating code.
Validator: .github/config_validator.rb
Validation checks (in order):
- API version is supported (v20111101 or v20250224)
- Config file exists at specified path
- Config file contains valid YAML
- Major version in config matches API version requirement
Error Message:
Error: Config file not found: openapi/config-v20111101.yml
Causes:
- Config file doesn't exist for selected API version
- Filename typo or wrong path
- API version not yet configured
Solutions:
- Verify file exists:
ls -la openapi/config-v*.yml - Check filename matches API version exactly
- For new API versions, create config file first (see Adding-a-New-API-Version.md)
Error Message:
Error: Invalid npm version for API v20250224
Expected: 3.x.x
Got: 2.0.0
Cause: Major version in config doesn't match API version
Semantic Versioning Rule:
- v20111101 API must use
npmVersion: 2.x.x - v20250224 API must use
npmVersion: 3.x.x - New APIs must use next sequential major version
Solution: Update config file with correct major version
---
npmName: mx-platform-node
npmVersion: 3.0.0 # Must start with 3 for v20250224
apiVersion: v20250224Error Message:
YAML syntax error in openapi/config-v20111101.yml
Common Issues:
- Incorrect indentation (YAML is whitespace-sensitive)
- Missing quotes around values with special characters
- Trailing spaces after values
- Invalid field names
How to Test:
ruby -e "require 'yaml'; puts YAML.load(File.read('openapi/config-v20111101.yml'))"If this errors, your YAML syntax is wrong.
Solution: Fix YAML syntax and re-test
---
generatorName: typescript-axios # Must start with ---
npmName: mx-platform-node
npmVersion: 2.0.0
apiVersion: v20111101
supportsES6: true
.openapi-generator-ignore: trueError Message:
npm ERR! 401 Unauthorized
npm ERR! need auth 401 Unauthorized - PUT https://registry.npmjs.org/mx-platform-node
Causes:
NPM_AUTH_TOKENsecret expired or revoked- Token doesn't have publish permissions for
mx-platform-node - Token was deleted from GitHub repository secrets
- Wrong npm registry configured
Solutions:
- Verify token exists: Go to GitHub repo → Settings → Secrets and variables → Actions → Look for
NPM_AUTH_TOKEN - If missing or expired, generate new token:
- Log into npm.js as maintainer
- Create new "Publish" scope token (not Read-only)
- Copy full token value
- Update secret in GitHub repository
- Verify token has permissions for
mx-platform-nodepackage - Wait 5 minutes after updating secret before retrying
Error Message:
npm ERR! 403 Forbidden - PUT https://registry.npmjs.org/mx-platform-node/2.0.5
You cannot publish over the previously published version 2.0.5
Cause: Version already exists on npm registry
Why This Happens:
- SDK was already published with this version number
- Version bump didn't increment (check
version.rboutput) - Wrong version directory being published
Solutions:
- If intentional, increment version and regenerate:
ruby .github/version.rb patch openapi/config-v20111101.yml
- If accidental duplicate:
- Check
openapi/config-v20111101.ymlhas next sequential version - Run generate workflow again to create PR with new version
- Merge PR to trigger publish with correct version
- Check
Error Message:
gh release create: error: failed to create release
fatal: A release with this tag already exists
Causes:
- Release tag already exists (e.g.,
v2.0.1) GITHUB_TOKENlacks release creation permissions- Typo in tag name
Solutions:
- Check if release already exists:
git tag -l | grep v2.0.1 - If release exists but workflow failed, delete it:
- Go to GitHub repo → Releases → Find the release
- Click "Delete" on the release
- Re-run the release workflow
- Verify
GITHUB_TOKENhas release creation permissions (usually auto-provided by GitHub) - Check that version in
package.jsonmatches tag format (v2.0.1, not2.0.1)
Scenario: Merged a PR for v20111101 only, but both v20111101 and v20250224 published
Causes:
- Changes were made to both
v20111101/andv20250224/directories - Unintended changes to both directories were committed
- Path filter in
on-push-master.ymlhas wrong syntax
Solutions:
- Review what changed in the merged PR:
git log --oneline -n 5 | head -1 git show <commit-hash> --name-status | grep -E "v20111101|v20250224"
- If only one version should have changed:
- Revert the commit
- Fix the unintended changes
- Create a new PR with only the intended changes
- If both versions should have changed:
- This is correct behavior (both path filters matched)
- Both versions published as expected
Symptom: Merged a PR that only modified v20250224/ files, but the publish job didn't run
Expected Behavior: publish-v20250224 should run when only v20250224 is modified
Root Cause: Previous versions of the workflow had dependencies that broke when intermediate jobs were skipped. This has been fixed with the delay job pattern.
Current Implementation (uses delay job pattern):
delay-for-v20250224runs independently of other versions- This delay job always runs (depends only on safety checks, not other versions)
- It provides a 2-second window for previous versions to start publishing first
- v20250224 publish depends on this delay (not on v20111101's release)
- Result: Publishing works correctly whether one or both versions are modified
If You're Still Seeing This Issue:
- Verify you have the latest
on-push-master.yml:grep -A 5 "delay-for-v20250224" .github/workflows/on-push-master.yml - Confirm the delay job is independent:
delay-for-v20250224: needs: [check-skip-publish, detect-changes] if: needs.check-skip-publish.outputs.skip_publish == 'false' steps: - name: Brief delay to stagger v20250224 publish run: sleep 2
- Ensure
publish-v20250224depends on the delay job:publish-v20250224: needs: [check-skip-publish, detect-changes, delay-for-v20250224]
- If not present, update workflow from latest template
Technical Details: See Workflow-and-Configuration-Reference.md in the "Publishing via on-push-master.yml" section for full delay job implementation details.
Symptom: Generated SDK doesn't include changes that were in the OpenAPI spec
Cause: GitHub's raw.githubusercontent.com CDN cached the old file for 5 minutes
Why This Happens:
- OpenAPI repo commits spec change at 2:00 PM
- Repository dispatch sent immediately at 2:01 PM
- Workflow runs at 2:02 PM but CDN still has 2:00 PM version
- SDK generated from stale spec
Solution: Already implemented in openapi-generate-and-push.yml
- Uses commit SHA in spec URL:
raw.githubusercontent.com/mxenabled/openapi/<commit-sha>/openapi/v20111101.yml - Commit SHA bypasses CDN and guarantees exact spec version
- Nothing to do—this is automatic
Manual Generation Note: generate.yml uses master branch reference (not commit SHA) because developer controls timing and doesn't have CDN race condition concern.
Symptom: After automated generation, SDK files appear at v20111101/generated-v20111101/api.ts instead of v20111101/api.ts
Cause: The Process-and-Push job in openapi-generate-and-push.yml downloads generated artifacts and moves them into the version directory. If the version directory already exists (from a prior commit), mv places the source inside the existing directory as a subdirectory rather than replacing it.
Solution: Already fixed in openapi-generate-and-push.yml. The workflow now runs rm -rf ./$VERSION before mv to ensure the target directory doesn't exist, so the move replaces rather than nests. If you see this issue, verify the workflow includes the rm -rf step before the mv command in the Process-and-Push job.
Symptom: Automated generation completes but the version in package.json didn't increment (stays at the previous version)
Cause: The version.rb script argument was quoted incorrectly in the workflow. Passing "$VERSION" (with surrounding quotes in the shell script) causes bash to pass the literal string $VERSION instead of its value, so version.rb receives an unrecognized bump type and silently fails.
Solution: Already fixed in openapi-generate-and-push.yml. The $VERSION variable is now passed unquoted to version.rb. If you see this issue, verify the workflow calls version.rb with $VERSION (not "$VERSION"):
# Correct
NEW_VERSION=$(ruby .github/version.rb $VERSION ${{ matrix.config_file }})
# Wrong — passes literal string
NEW_VERSION=$(ruby .github/version.rb "$VERSION" ${{ matrix.config_file }})Symptom: Merged a PR with changes to v20111101/ directory, but on-push-master.yml didn't run
Causes:
- Path filter in
on-push-master.ymlhas syntax error or wrong path - Changes were not actually in the version directory
- Commit was made to wrong branch
- Workflow file has syntax error
- (Automated flow only) The push was made with
GITHUB_TOKEN, which does not triggerpushevents for other workflows
Solutions:
- Verify path filter syntax is correct:
on: push: branches: [master] paths: - 'v20111101/**' # Correct format - 'v20250224/**' repository_dispatch: types: [automated_push_to_master]
- Check what files were actually changed:
git diff HEAD~1..HEAD --name-only | grep -E "v20111101|v20250224"
- Verify commit was to
masterbranch:git log --oneline -n 1 git branch -r --contains HEAD
- Check
on-push-master.ymlsyntax:ruby -e "require 'yaml'; puts YAML.load(File.read('.github/workflows/on-push-master.yml'))" - For automated flows: Verify that
openapi-generate-and-push.ymlsends arepository_dispatchevent after pushing. Thepushtrigger only works for manual PR merges. Automated pushes from workflows useGITHUB_TOKEN, which does not trigger other workflows — the generate workflow must send an explicitrepository_dispatch(type:automated_push_to_master) using a GitHub App token.
Symptom: Added [skip-publish] to commit message but workflow still published
Causes:
- Flag syntax wrong (case-sensitive, needs brackets)
- Flag in PR title/body instead of commit message
- Commit message doesn't include the flag
Solution: Commit message must include exact text [skip-publish]
# Correct
git commit -m "Migrate SDK structure [skip-publish]"
# Wrong - will not work
git commit -m "Migrate SDK structure [SKIP-PUBLISH]"
git commit -m "Migrate SDK structure (skip-publish)"
git commit -m "Migrate SDK structure skip-publish"Symptom: The check-skip-publish step in on-push-master.yml errors with something like SDK: command not found (exit code 127), and downstream jobs skip unexpectedly
Cause: The commit message contains double quotes (e.g., Revert "Generated SDK versions: v20111101"). If the workflow uses inline ${{ }} interpolation to assign the commit message, the inner quotes close the outer quotes in bash, causing the remaining text to be interpreted as commands.
Example of broken pattern:
# BROKEN - double quotes in commit message break this
COMMIT_MSG="${{ github.event.head_commit.message }}"Solution: The workflow should use an env: block to pass the commit message safely:
- name: Check for [skip-publish] flag in commit message
id: check
env:
COMMIT_MSG: ${{ github.event.head_commit.message }}
run: |
if [[ "$COMMIT_MSG" == *"[skip-publish]"* ]]; then
echo "skip_publish=true" >> $GITHUB_OUTPUT
else
echo "skip_publish=false" >> $GITHUB_OUTPUT
fiThis fix is already applied to on-push-master.yml. If you see this error, verify that the workflow is using the env: block pattern and not inline interpolation.
Error: Version directory parameter required. Usage: ruby clean.rb <version_dir>
Cause: clean.rb called without version directory argument
Solution: Always provide version directory
ruby .github/clean.rb v20111101 # Correct
ruby .github/clean.rb # Wrong - missing parameterError: Invalid version bump type: major. Supported: 'minor' or 'patch'
Cause: Tried to use major option (not allowed for semantic versioning)
Solution: Use only minor or patch
ruby .github/version.rb patch openapi/config-v20111101.yml # Correct
ruby .github/version.rb major openapi/config-v20111101.yml # Wrong - major not allowedError: Config file not found: openapi/config-invalid.yml
Cause: Config file path doesn't exist
Solution: Verify file path and spelling
ls -la openapi/config-v*.yml # List valid files
ruby .github/version.rb patch openapi/config-v20111101.yml # Use correct pathError Message (in GitHub Actions UI):
Invalid workflow file
Common Causes:
- YAML indentation error
- Invalid GitHub Actions syntax
- Missing required fields
- Circular job dependencies
How to Debug:
- Go to GitHub repo → Actions → Select failed workflow
- Click on the workflow run
- Look for error message at top (usually shows line number)
- Check YAML syntax locally:
ruby -e "require 'yaml'; YAML.load_file('.github/workflows/on-push-master.yml')"
Most Common Fix: Indentation
- GitHub Actions workflows are YAML files
- Indentation must be consistent (usually 2 spaces)
- Use an editor with YAML validation
If you encounter an issue not covered above:
- Check workflow logs: Go to GitHub repo → Actions → Failed workflow → Click run → Expand failed step
- Review error message: Look for specific file names, line numbers, or error codes
- Check recent changes: Did a recent PR change workflows or configs?
- Test locally: Try running Ruby scripts manually to verify syntax
- Ask the team: Reference the error message and steps to reproduce
- Multi-Version-SDK-Flow.md - Architecture overview
- Workflow-and-Configuration-Reference.md - Detailed implementation
- Adding-a-New-API-Version.md - Step-by-step guide for new versions