How to diagnose and resolve issues with apiops-cli.
The most powerful diagnostic tool. Debug logging shows:
- Full authentication flow — which credential source was tried and selected
- Every Azure API call — URL, method, response status
- Resource processing steps — which resources are being extracted/published and in what order
- Dependency resolution — which transitive dependencies were discovered
apiops extract \
--log-level debug \
--subscription-id "$SUB_ID" \
--resource-group mygroup \
--service-name myapim \
--output ./artifactsPreview what would change without modifying anything:
apiops publish \
--dry-run \
--subscription-id "$SUB_ID" \
--resource-group mygroup \
--service-name myapim \
--source ./artifactsThe dry-run report shows which resources would be created, updated, or deleted.
Get machine-readable output for scripting and analysis:
apiops extract --format json ... 2>debug.log | jq '.'Check extracted files directly:
# Verify JSON files are valid
find ./artifacts -name "*.info.json" | xargs -I {} sh -c 'jq . "{}" > /dev/null || echo "Invalid: {}"'
# Inspect a specific API's policy
cat ./artifacts/apis/petstore/policy.xml
# Check named value references in policies
grep -r "{{.*}}" ./artifacts --include="*.xml"Follow this checklist when troubleshooting:
apiops extract --log-level debug ...Look for the first error or warning in the output. Debug logs are written to stderr, so stdout remains clean for --format json data.
Is DefaultAzureCredential finding valid credentials?
# Verify Azure CLI is logged in
az account show
# Verify the correct subscription is selected
az account show --query '{subscription: id, tenant: tenantId}'In debug logs, look for lines indicating which credential source succeeded:
"Using EnvironmentCredential"— service principal via env vars"Using AzureCliCredential"— Azure CLI login"Using ManagedIdentityCredential"— managed identity
Can you reach the APIM management endpoint?
# Test Azure management API
curl -s -o /dev/null -w "%{http_code}" https://management.azure.com
# Test with authentication
az rest --method GET \
--url "https://management.azure.com/subscriptions/$SUB_ID/resourceGroups/$RG/providers/Microsoft.ApiManagement/service/$APIM?api-version=2024-05-01"Does the identity have the required role?
# List role assignments for the APIM resource
az role assignment list \
--scope "/subscriptions/$SUB_ID/resourceGroups/$RG/providers/Microsoft.ApiManagement/service/$APIM" \
--output table| Operation | Minimum role |
|---|---|
| Extract | API Management Service Reader |
| Publish | API Management Service Contributor |
Are the JSON files valid? Are policies well-formed XML?
# Check all JSON files parse correctly
find ./artifacts -name "*.json" -exec sh -c 'jq empty "$1" 2>/dev/null || echo "Bad JSON: $1"' _ {} \;
# Check XML policies for syntax issues
find ./artifacts -name "*.xml" -exec xmllint --noout {} \; 2>&1 | grep -v "^$"Before a real publish, run with --dry-run and verify the changes match your expectations:
apiops publish --dry-run --format json ... | jq '.changes[]'| Stream | Content |
|---|---|
| stdout | Command output (text or JSON via --format json) |
| stderr | Log messages (debug, info, warn, error) |
This separation means you can redirect logs without corrupting output:
# Capture logs to a file, output to stdout
apiops extract --log-level debug ... 2>extract-debug.log
# Capture output to a file, logs to terminal
apiops extract --format json ... >artifacts.json| Level | What it shows | When to use |
|---|---|---|
debug |
API call details, auth flow, resource processing steps | Diagnosing specific failures |
info |
Progress messages, resource counts | Normal operation (default) |
warn |
Non-fatal issues (git not found, commit not found) | Reviewing potential problems |
error |
Failures that affect the exit code | Always shown |
The logger automatically redacts sensitive values. Fields matching these patterns are replaced with [REDACTED]:
token,secret,password,keyauthorizationheadersclient_secret,access_token
You can safely share debug logs without exposing credentials.
- Enable
--log-level debugand check if the LIST API calls return empty arrays - Verify the APIM service name, resource group, and subscription are correct
- If using
--filter, check that the filter file matches existing APIs - Check RBAC —
Readerrole is required at minimum
- Run with
--dry-runto see the comparison output - If using
--commit-id, verify the commit hash exists in the repository - Check that the artifact directory (
--source) points to the correct path - Verify that artifact files have actually changed since the last publish
- Verify the
--commit-idvalue is the correct base commit - If the commit was rebased or amended, the diff may not capture all changes
- Solution: omit
--commit-idfor a full publish, or use the correct base commit
- In CI/CD,
DefaultAzureCredentialuses different credential sources than local dev - Check that the CI/CD environment has the required secrets/variables configured
- For GitHub Actions with OIDC: verify the federated credential subject matches the workflow
- For Azure DevOps: verify the service connection is configured correctly
- Common Errors — Error message reference with solutions
- Pipeline Recovery — Recovering from failed CI/CD runs
- Authentication Guide — Full auth setup reference