YAML Validation
Validate curl-runner YAML configuration files against the schema. Discover issues, get fix suggestions, and auto-fix common problems.
Feature overview →Validate curl-runner YAML configuration files against the schema. Discover issues, get fix suggestions, and auto-fix common problems with a single command.
Overview
The curl-runner validate command provides comprehensive validation of your YAML configuration files. It checks structure, required fields, valid values, security issues, and common typos—with intelligent suggestions and auto-fix capabilities.
- Schema Validation: Full curl-runner schema validation
- Auto-Fix: Many issue types fix themselves with
--fix - Typo Detection: Smart suggestions for misspellings
- Security Checks: Detects hardcoded secrets & keys
Basic Usage
Run curl-runner validate to check your YAML files.
# Validate all YAML files in current directory
curl-runner validate
# Validate specific file
curl-runner validate api.yaml
# Validate directory
curl-runner validate tests/
# Validate with glob pattern
curl-runner validate "tests/**/*.yaml"CLI Options
-
-f, --fix: Automatically fix issues where possible. Fixes URL issues, method casing, header casing, and more. -
-s, --strict: Treat warnings as errors. Useful for CI pipelines where you want stricter validation. -
-q, --quiet: Only show files with issues. Valid files are not printed. -
-h, --help: Show help message and exit.
# Treat warnings as errors (for CI)
curl-runner validate --strict
# Short form
curl-runner validate -s
# Combine with quiet mode
curl-runner validate --strict --quietAuto-Fix
Use --fix to automatically fix common issues.
# Validate and auto-fix issues
curl-runner validate --fix
# Short form
curl-runner validate -f
# Fix quietly (only show errors)
curl-runner validate -fq
# Fix specific files
curl-runner validate api.yaml --fixAuto-Fixable Issues
- Lowercase HTTP methods → UPPERCASE
- Missing
https://prefix - Protocol typos (htps, htpp, etc.)
- Hostname typos (locahost, etc.)
- Double slashes in URL paths
- Spaces in URLs → %20
- Header casing (content-type → Content-Type)
- Lowercase execution mode
- Lowercase output format
- Lowercase prettyLevel
Manual Fix Required
- Invalid auth types
- Missing required fields (url)
- Invalid status codes
- Schema conflicts (body + formData)
- Unknown keys with no suggestion
- Invalid port numbers
- Hardcoded credentials
- Invalid JSON body
Output Examples
The validate command provides clear, colorized output showing what passed, what failed, and the severity of each issue.
curl-runner validate
Files: 5 found
✓ api/invalid.yaml
● request.url: URL should start with http:// or https://
fix: Prepend https://
● request.method: Method should be uppercase: "GET"
fix: Change to "GET"
● request.headers.content-type: Header "content-type" should be "Content-Type" for consistency
fix: Rename to "Content-Type"
● request.insecure: Insecure mode disables SSL verification
→ 3 warning(s), 1 info
✓ api/orders.yaml
✓ api/posts.yaml
✓ api/products.yaml
✓ api/users.yaml
All files valid!Files with warnings still count as valid. With --strict they fail:
curl-runner validate --strict -q
Files: 5 found
✗ api/invalid.yaml
● request.insecure: Insecure mode disables SSL verification
→ 1 warning(s)
Summary: 1 file(s) with 1 issue(s)With auto-fix enabled:
curl-runner validate --fix
Files: 5 found
✓ api/invalid.yaml
● request.url: URL should start with http:// or https://
● request.method: Method should be uppercase: "GET"
● request.headers.content-type: Header "content-type" should be "Content-Type" for consistency
● request.insecure: Insecure mode disables SSL verification
✓ Fixed 3 issue(s)
→ 3 warning(s), 1 info
✓ api/orders.yaml
✓ api/posts.yaml
✓ api/products.yaml
✓ api/users.yaml
All files valid!Auto-fix rewrites the file
--fix writes the file back in place and re-serializes the YAML, so formatting and comments are
not preserved. Review the diff before committing.
URL Validations
Comprehensive URL validation with typo detection and auto-fix capabilities.
# URL Validations
# Missing protocol (warning, auto-fixable)
request:
url: api.example.com/users$ curl-runner validate missing-protocol.yaml
✓ missing-protocol.yaml
● request.url: URL should start with http:// or https://
fix: Prepend https://
→ 1 warning(s)
All files valid!# Protocol typo (error, auto-fixable)
request:
url: htps://api.example.com$ curl-runner validate protocol-typo.yaml
✗ protocol-typo.yaml
● request.url: URL contains typo "htps"
fix: Fix to "https"
→ 1 error(s)
Summary: 1 file(s) with 1 issue(s)# Hostname typo (error, auto-fixable)
request:
url: https://locahost:3000/api$ curl-runner validate hostname-typo.yaml
✗ hostname-typo.yaml
● request.url: URL contains typo "locahost"
fix: Fix to "localhost"
→ 1 error(s)
Summary: 1 file(s) with 1 issue(s)# Double slash in path (warning, auto-fixable)
request:
url: https://api.example.com//users$ curl-runner validate double-slash-in-path.yaml
✓ double-slash-in-path.yaml
● request.url: URL contains double slashes in path
fix: Remove extra slashes
→ 1 warning(s)
All files valid!# Spaces in URL (error, auto-fixable)
request:
url: https://api.example.com/users /list$ curl-runner validate spaces-in-url.yaml
✗ spaces-in-url.yaml
● request.url: URL contains spaces
fix: Encode spaces as %20
→ 1 error(s)
Summary: 1 file(s) with 1 issue(s)# Invalid port (error)
request:
url: https://api.example.com:99999/api$ curl-runner validate invalid-port.yaml
✗ invalid-port.yaml
● request.url: Invalid port number 99999. Must be 1-65535
→ 1 error(s)
Summary: 1 file(s) with 1 issue(s)- Detected URL Typos
htpp→ httphtps→ httpshtp→ httphttpss→ httpslocahost→ localhostlocalhsot→ localhostlocalhos→ localhostlcoalhost→ localhost
Header Validations
Validates header names, detects duplicates, and checks Content-Type consistency.
# Header Validations
# Wrong casing (info, auto-fixable)
request:
url: https://api.example.com
headers:
content-type: application/json
authorization: Bearer token$ curl-runner validate wrong-casing.yaml
✓ wrong-casing.yaml
● request.headers.content-type: Header "content-type" should be "Content-Type" for consistency
fix: Rename to "Content-Type"
● request.headers.authorization: Header "authorization" should be "Authorization" for consistency
fix: Rename to "Authorization"
→ 2 info
All files valid!# Missing Content-Type (info)
request:
url: https://api.example.com
method: POST
body:
name: test$ curl-runner validate missing-content-type.yaml
✓ missing-content-type.yaml
● request.headers: Body present but no Content-Type header; consider adding one
→ 1 info
All files valid!# Duplicate headers (warning)
request:
url: https://api.example.com
headers:
Content-Type: application/json
content-type: text/plain$ curl-runner validate duplicate-headers.yaml
✓ duplicate-headers.yaml
● request.headers.content-type: Header "content-type" should be "Content-Type" for consistency
fix: Rename to "Content-Type"
● request.headers.content-type: Duplicate header "content-type" (case-insensitive match with "Content-Type")
→ 1 warning(s), 1 info
All files valid!- Standard Header Casing
- Content-Type
- Authorization
- Accept
- Cache-Control
- Content-Length
- User-Agent
- X-Requested-With
- X-API-Key
- Accept-Encoding
Security Validations
Detects potential security issues like hardcoded credentials and API keys.
# Security Validations
# Hardcoded credentials (warning)
request:
url: https://api.example.com
auth:
type: basic
username: admin
password: secret123$ curl-runner validate hardcoded-credentials.yaml
✓ hardcoded-credentials.yaml
● request.auth.password: Hardcoded password. Consider using "${env.PASSWORD}"
→ 1 warning(s)
All files valid!# JWT in header (warning)
request:
url: https://api.example.com
headers:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.signature$ curl-runner validate jwt-in-header.yaml
✓ jwt-in-header.yaml
● request.headers.Authorization: Potentially sensitive header value. Consider using variables like "${env.TOKEN}"
→ 1 warning(s)
All files valid!# API key patterns (warning)
request:
url: https://api.example.com
headers:
X-API-Key: sk-live-xxxxxxxxxxxxx$ curl-runner validate api-key-patterns.yaml
✓ api-key-patterns.yaml
● request.headers.X-API-Key: Potentially sensitive header value. Consider using variables like "${env.TOKEN}"
→ 1 warning(s)
All files valid!# Insecure mode (warning)
request:
url: https://api.example.com
insecure: true$ curl-runner validate insecure-mode.yaml
✓ insecure-mode.yaml
● request.insecure: Insecure mode disables SSL verification
→ 1 warning(s)
All files valid!Detected Patterns
- JWT tokens (Bearer eyJ...)
- Stripe API keys (sk_live_, sk_test_)
- AWS access keys (AKIA...)
- Common password field names (password, passwd, secret, api_key, etc.)
- Hardcoded bearer tokens
- Insecure SSL mode
Unknown Key Detection
Detects unknown configuration keys and suggests corrections using edit distance matching.
# Unknown Key Detection with Suggestions
# Typo in key name
request:
url: https://api.example.com
methood: GET$ curl-runner validate typo-in-key-name.yaml
✓ typo-in-key-name.yaml
● request.methood: Unknown key "methood" (did you mean "method"?)
fix: Rename to "method"
→ 1 warning(s)
All files valid!
# Typo in nested key
request:
url: https://api.example.com
auth:
tpye: bearer
token: ${TOKEN}$ curl-runner validate typo-in-nested-key.yaml
✗ typo-in-nested-key.yaml
● request.auth.tpye: Unknown key "tpye" (did you mean "type"?)
fix: Rename to "type"
● request.auth.type: Auth type is required
→ 1 error(s), 1 warning(s)
Summary: 1 file(s) with 2 issue(s)# Global config typo
global:
excution: parallel
requests:
- url: https://api.example.com$ curl-runner validate global-config-typo.yaml
✓ global-config-typo.yaml
● global.excution: Unknown key "excution" (did you mean "execution"?)
fix: Rename to "execution"
→ 1 warning(s)
All files valid!What Gets Validated
The validator checks all aspects of your curl-runner configuration.
Structure
- Must have
request,requests, orcollection - Unknown keys are flagged with suggestions
- Valid YAML syntax
- Duplicate request names detected
Request Fields
url- Required, validated formatmethod- GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONSheaders- Casing, duplicatesbody- JSON validation, method compatibility
Authentication
auth.type- basic, bearer, digest, ntlm or oauth2- basic auth requires username
- bearer auth requires token
- Hardcoded credential detection
SSL/TLS Config
- cert without key is flagged
- key without cert is flagged
- Path values must be strings
- Insecure mode warning
Expect Assertions
- Status codes must be 100-599
- Response time format validation
- Headers must be an object
- Duration format (e.g.,
<500ms)
Global Config
- execution: sequential or parallel
- output.format: json, pretty, raw
- output.prettyLevel: minimal, standard, detailed
- ci.failOnPercentage: 0-100
Timeouts & Retries
- timeout must be positive number
- retry.count must be non-negative
- retry.delay must be non-negative
- retry.maxDelay must be non-negative
Proxy Config
- proxy.url must be valid URL
- proxy.auth requires username
- Proxy URL protocol validation
Valid Configuration Examples
Here are examples of properly configured YAML files that pass validation.
# Valid request configuration
request:
name: Get User
url: https://api.example.com/users/1
method: GET
headers:
Authorization: Bearer ${TOKEN}
Content-Type: application/json
timeout: 5000
expect:
status: 200
headers:
content-type: application/json
body:
id: 1Global configuration:
# Valid global configuration
global:
execution: parallel
maxConcurrency: 5
continueOnError: true
output:
format: pretty
prettyLevel: detailed
ci:
strictExit: true
failOn: 2
requests:
- url: https://api.example.com/users
- url: https://api.example.com/postsCommon Validation Errors
Here are examples of common validation errors and how to fix them.
# Common validation errors
# Missing URL (error)
request:
method: GET$ curl-runner validate missing-url.yaml
✗ missing-url.yaml
● request.url: URL is required
→ 1 error(s)
Summary: 1 file(s) with 1 issue(s)# Invalid method (error)
request:
url: https://api.example.com
method: INVALID$ curl-runner validate invalid-method.yaml
✗ invalid-method.yaml
● request.method: Invalid method "INVALID". Must be: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS
→ 1 error(s)
Summary: 1 file(s) with 1 issue(s)# Lowercase method (warning, auto-fixable)
request:
url: https://api.example.com
method: get$ curl-runner validate lowercase-method.yaml
✓ lowercase-method.yaml
● request.method: Method should be uppercase: "GET"
fix: Change to "GET"
→ 1 warning(s)
All files valid!# Invalid auth type (error)
request:
url: https://api.example.com
auth:
type: oauth$ curl-runner validate invalid-auth-type.yaml
✗ invalid-auth-type.yaml
● request.auth.type: Invalid auth type "oauth". Must be: basic, bearer, digest, ntlm, oauth2
fix: Change to "oauth2"
→ 1 error(s)
Summary: 1 file(s) with 1 issue(s)# Invalid status code (error)
request:
url: https://api.example.com
expect:
status: 1000$ curl-runner validate invalid-status-code.yaml
✗ invalid-status-code.yaml
● request.expect.status: Status code must be a number between 100-599
→ 1 error(s)
Summary: 1 file(s) with 1 issue(s)# Body and formData conflict (error)
request:
url: https://api.example.com
body: { "test": "value" }
formData:
field: value$ curl-runner validate body-and-formdata-conflict.yaml
✗ body-and-formdata-conflict.yaml
● request.headers: Body present but no Content-Type header; consider adding one
● request: Cannot use both "body" and "formData"
● request.body: Body with GET method may be ignored by some servers
→ 1 error(s), 1 warning(s), 1 info
Summary: 1 file(s) with 3 issue(s)# Body with GET (warning)
request:
url: https://api.example.com
method: GET
body: { "test": "value" }$ curl-runner validate body-with-get.yaml
✓ body-with-get.yaml
● request.headers: Body present but no Content-Type header; consider adding one
● request.body: Body with GET method may be ignored by some servers
→ 1 warning(s), 1 info
All files valid!# Duplicate request names (warning)
requests:
- name: GetUser
url: https://api.example.com/users/1
- name: GetUser
url: https://api.example.com/users/2$ curl-runner validate duplicate-request-names.yaml
✓ duplicate-request-names.yaml
● requests[1]: Duplicate request name "GetUser" (also at requests[0])
→ 1 warning(s)
All files valid!CI/CD Integration
Use validation in your CI/CD pipeline to catch configuration errors before deployment.
# GitHub Actions
- name: Validate YAML configs
run: curl-runner validate tests/ --quiet
# GitLab CI (strict mode fails on warnings)
validate:
script:
- curl-runner validate tests/ --strict
# Pre-commit hook
curl-runner validate && curl-runner tests/Exit Codes
0- All files valid (no errors)1- One or more files have errors1(with --strict) - Files have errors OR warnings
Best Practices
- Recommended
- Run validation before committing changes
- Use --strict in CI pipelines
- Use --quiet in automated scripts
- Review auto-fixes before committing
- Use environment variables for credentials
- Validate entire test directories at once
- Considerations
- Auto-fix changes files in place
- Some issues require manual intervention
- Warnings don't fail validation (unless --strict)
- Variables (
${VAR}) are not resolved during validation - Security warnings suggest using env vars
Severity Levels
Each issue is printed with a colored ●; the color shows the severity and the summary line counts each level.
- Error (red): Must be fixed. Fails validation.
- Warning (yellow): Should be fixed. Often auto-fixable. Valid by default, fails with
--strict. - Info (dim): For awareness. Does not affect the exit code.