6.8 KiB
Buildkite URL Parsing Reference
This document explains Buildkite URL formats and how to extract information from them.
URL Formats
Buildkite uses several URL patterns for builds and jobs:
Build URL (Most Common)
https://buildkite.com/{org}/{pipeline}/builds/{number}
Example:
https://buildkite.com/gusto/payroll-building-blocks/builds/29627
Extracting:
org: "gusto"pipeline: "payroll-building-blocks"number: "29627"
Step/Job URL (From Build Page)
https://buildkite.com/{org}/{pipeline}/builds/{number}/steps/{view}?sid={step-id}
Example:
https://buildkite.com/gusto/payroll-building-blocks/builds/29627/steps/canvas?sid=019a5f23-8109-4656-a033-bd62a82ca239
Extracting:
org: "gusto"pipeline: "payroll-building-blocks"number: "29627"view: "canvas" (UI view type)sid: "019a5f23-8109-4656-a033-bd62a82ca239" (step ID)
IMPORTANT: The sid (step ID) is NOT the same as job UUID. See "Step IDs vs Job UUIDs" below.
Job Detail URL
https://buildkite.com/{org}/{pipeline}/builds/{number}/jobs/{job-uuid}
Example:
https://buildkite.com/gusto/payroll-building-blocks/builds/29627/jobs/019a5f20-2d30-4c67-9edd-87fb92e1f487
Extracting:
org: "gusto"pipeline: "payroll-building-blocks"number: "29627"job-uuid: "019a5f20-2d30-4c67-9edd-87fb92e1f487"
NOTE: This format contains the actual job UUID needed for log retrieval.
Step IDs vs Job UUIDs
Critical distinction: Buildkite has two types of identifiers that are easily confused.
Step IDs
- Source: Query parameter
sidin step URLs - Format: ULID format (e.g.,
019a5f23-8109-4656-a033-bd62a82ca239) - Purpose: Frontend UI routing
- Use: Navigating to specific steps in web UI
- API Usage: ❌ NOT accepted by MCP tools
Job UUIDs
- Source:
uuidfield in API responses - Format: ULID format (e.g.,
019a5f20-2d30-4c67-9edd-87fb92e1f487) - Purpose: Backend job identification
- Use: API calls to get logs, job details, etc.
- API Usage: ✅ Required by MCP
get_logstool
Why the Confusion?
Both use ULID format (starts with 019a5f...), but:
- Step IDs come from URLs → Web UI routing
- Job UUIDs come from API responses → Backend identification
You cannot use a step ID for log retrieval. Always get job UUID from buildkite:get_build API.
Resolving Step ID to Job UUID
When given a step URL with sid parameter:
Step 1: Extract build identifiers
// From: https://buildkite.com/gusto/payroll-building-blocks/builds/29627/steps/canvas?sid=019a5f23...
const org = 'gusto';
const pipeline = 'payroll-building-blocks';
const build = '29627';
// Ignore the sid parameter
Step 2: Get job details from API
mcp__MCPProxy__call_tool('buildkite:get_build', {
org_slug: org,
pipeline_slug: pipeline,
build_number: build,
detail_level: 'detailed',
job_state: 'failed', // If investigating failures
});
Step 3: Match job by properties
The API response includes all jobs. Match by:
labelfield (e.g., "ste rspec", "Rubocop")statefield (e.g., "failed")typefield (e.g., "script")step_keyfield if available
Step 4: Extract job UUID
// From API response
const job = response.jobs.find(
(j) => j.label === 'ste rspec' && j.state === 'failed'
);
const jobUuid = job.uuid; // e.g., "019a5f20-2d30-4c67-9edd-87fb92e1f487"
Step 5: Use job UUID for logs
mcp__MCPProxy__call_tool('buildkite:get_logs', {
org_slug: org,
pipeline_slug: pipeline,
build_number: build,
job_id: jobUuid, // NOT the step ID from URL
});
Parsing Logic
Simple Regex Approach
function parseBuildkiteUrl(url) {
// Match build URL pattern
const buildMatch = url.match(
/buildkite\.com\/([^/]+)\/([^/]+)\/builds\/(\d+)/
);
if (!buildMatch) {
throw new Error('Invalid Buildkite URL');
}
return {
org: buildMatch[1],
pipeline: buildMatch[2],
buildNumber: buildMatch[3],
};
}
// Usage
const info = parseBuildkiteUrl(
'https://buildkite.com/gusto/payroll-building-blocks/builds/29627'
);
// => { org: "gusto", pipeline: "payroll-building-blocks", buildNumber: "29627" }
Extracting Step ID (If Needed)
function parseStepUrl(url) {
const base = parseBuildkiteUrl(url);
// Extract step ID from query parameter
const sidMatch = url.match(/[?&]sid=([^&]+)/);
return {
...base,
stepId: sidMatch ? sidMatch[1] : null,
};
}
// Usage
const info = parseStepUrl(
'https://buildkite.com/gusto/payroll-building-blocks/builds/29627/steps/canvas?sid=019a5f23...'
);
// => { org: "gusto", pipeline: "payroll-building-blocks", buildNumber: "29627", stepId: "019a5f23..." }
Remember: The stepId is useful for debugging but cannot be used for API calls. Always fetch job UUID from the API.
Common URL Patterns in Practice
Pattern 1: User Shares Failing Build URL
URL: https://buildkite.com/org/pipeline/builds/123
Workflow:
- Extract org/pipeline/build
- Call
get_buildwithdetail_level: "summary" - Check build state
- If failed, call
get_buildwithdetail_level: "detailed"andjob_state: "failed" - Get logs for each failed job
Pattern 2: User Shares Step URL (Clicked on Specific Job)
URL: https://buildkite.com/org/pipeline/builds/123/steps/canvas?sid=019a5f23...
Workflow:
- Extract org/pipeline/build (ignore
sid) - Call
get_buildwithdetail_level: "detailed" - Find job matching user's intent (often the failed one)
- Extract job UUID
- Get logs for that job
The sid hints at which job the user was looking at, but you must resolve it via the API.
Pattern 3: User Provides Job UUID Directly
URL: https://buildkite.com/org/pipeline/builds/123/jobs/019a5f20-...
Workflow:
- Extract org/pipeline/build/job-uuid
- Call
get_logsdirectly with the job UUID - No resolution needed - this is the actual job UUID
This is the ideal format but least common in practice.
Edge Cases
Multiple Jobs with Same Label
Some pipelines parallelize jobs:
- "rspec (1/10)"
- "rspec (2/10)"
- "rspec (3/10)"
When resolving, match the full label string including the partition number.
Dynamic Pipeline Steps
Some pipelines generate steps dynamically. The step structure may not be predictable from the URL alone. Always query the API to see actual job structure.
Retried Jobs
When jobs are retried, multiple job UUIDs exist for the same step. The API returns the most recent attempt. Check retries_count and retry_source fields if investigating retry behavior.
See Also
- SKILL.md - Main skill documentation
- tool-capabilities.md - Tool limitations and capabilities
- troubleshooting.md - Common errors