Sentry ExecModule
Overview
SentryModule connects ValkyrAI workflows to Sentry's REST API through the native map I/O ExecModule ABI. Workflow Studio discovers it as SentryModule; internal-integration and auth tokens are resolved only from a bound encrypted IntegrationAccount.
The first production operation set focuses on agentic error triage and release evidence:
list_organizations,list_teams,list_projects,get_projectlist_issues,get_issue,update_issuelist_events,get_eventlist_releases,get_release,create_release
List operations use Sentry's cursor pagination without following provider-returned absolute URLs. Provider responses and errors are bounded and redacted. Only GET requests retry automatically; issue updates and release creation run once so an ambiguous timeout cannot duplicate an audit mutation.
Usage
- Create a dedicated Sentry internal integration for the target organization.
- Grant only the organization, project, issue, event, and release permissions required by the workflow.
- Store the token in the encrypted
apiKeyfield of anIntegrationAccountand set the account status toREADY. - Bind the account through
ExecModuleConfig.authConfig.integrationAccount. - Discover organization/project slugs with list operations.
- Use issue/event reads to collect evidence before changing issue state or creating a release.
Workflow input cannot provide a credential or redirect requests to an arbitrary host. The module builds every path from validated identifiers under Sentry's fixed API base.
Inputs
| Name | Type | Requirement | Default | Description and constraints |
|---|---|---|---|---|
operation | string | Required | None | One of the twelve operations above. |
organizationSlug | string | Organization/project/release operations | None | 1–80 letters, digits, _, or -; must start alphanumeric. |
projectSlug | string | Project/issue/event operations | None | Same bounded slug rule. |
issueId | string | Issue get/update | None | Numeric provider ID, maximum 32 digits. |
eventId | string | get_event | None | Numeric or 32–64-character hexadecimal provider ID. |
version | string | Release get/create | None | Caller-owned release version; 1–200 bounded version characters. |
query | string | Optional list_issues filter | None | Sentry structured search, maximum 2,048 characters. |
statsPeriod | string | Optional issue filter | 24h | 24h or 14d. |
full | boolean | Optional event filter | true | Include full event details when supported. |
issueStatus | string | Optional update | None | resolved, resolvedInNextRelease, unresolved, or ignored. |
assignedTo | string | Optional update | None | Actor ID, username, or team selector, maximum 200 characters. |
hasSeen | boolean | Optional update | None | User-context seen flag. |
isBookmarked | boolean | Optional update | None | Bookmark state. |
isSubscribed | boolean | Optional update | None | Subscription state. |
isPublic | boolean | Optional update | None | Sentry issue sharing state; not an authorization substitute. |
issue | object or JSON string | Optional update | None | Allowlisted issue fields only; 512 KiB cap. |
projects | array or JSON string | Optional release creation | None | 1–100 validated project slugs when supplied. |
releaseUrl | string | Optional release creation | None | HTTPS URL without embedded credentials, maximum 2,048 characters. |
dateReleased | string | Optional release creation | None | Provider-compatible ISO-8601 timestamp, maximum 64 characters. |
ref | string | Optional release creation | None | Source-control reference, maximum 250 characters. |
release | object or JSON string | Optional release creation | None | Allowlisted Sentry release fields; 512 KiB cap. |
cursor | string | Optional list continuation | None | Opaque non-whitespace cursor, maximum 4,096 characters. |
limit | integer | Optional | 100 | Maximum returned resources, 1–10,000. |
returnAll | boolean | Optional | false | Continue cursor pages to exhaustion or the 10,000-item cap. |
requestId | string | Optional | None | Caller correlation value sent as X-Request-Id, maximum 128 characters. |
The issue object accepts only status, assignedTo, hasSeen, isBookmarked, isSubscribed, and isPublic. The release object accepts only version, projects, url, dateReleased, ref, refs, and commits. Typed inputs override matching fields. update_issue rejects an empty mutation. create_release always requires the typed version input.
Outputs
| Name | Type | When present | Description |
|---|---|---|---|
status | string | Always | success or error. |
operation | string | Always | Normalized operation name. |
attempts | integer | Always | Total provider attempts across pages. |
httpStatus | integer | Provider responded | Last provider HTTP status. |
data | object | Single-resource/mutation success | Provider project, issue, event, or release. |
id, slug, shortId, version, permalink | string | Provider returns field | Safe convenience identity/link fields. |
items / count | array / integer | List success | Bounded provider resources and emitted count. |
hasMore / nextCursor | boolean / string | List success | Provider continuation state and opaque cursor. |
requestId | string | Provider supplies one | Safe provider trace reference. |
error | object | Failure | Safe {code, message, httpStatus?, retryable} details. |
Tokens and authorization headers never enter outputs. Provider messages pass through ValkyrAI's shared workflow sensitive-data policy.
IntegrationAccount Requirements
| Setting | Requirement |
|---|---|
| Provider | Sentry internal integration token or compatible auth token |
| Authentication | Authorization: Bearer <token> |
accountName | Human-readable automation identity |
apiKey | Preferred encrypted SecureField containing the token |
password | Legacy encrypted fallback only; prefer apiKey |
status | READY or legacy unset status; CLOSED and ERROR fail closed |
Recommended permission mapping:
- discovery: organization/project read;
- incident triage: issue and event read;
- issue state changes: issue write;
- release discovery/creation: release read/write.
Tokens remain inside IntegrationAccount. OAuth refresh and token rotation belong to the platform integration-account lifecycle, not workflow inputs.
Configuration
{
"version": "1.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:sentry-incident-automation"
},
"retryPolicy": {
"maxAttempts": 3,
"backoffStrategy": "EXPONENTIAL",
"initialDelayMs": 1000,
"maxDelayMs": 60000,
"jitter": false
},
"executionConfig": {"timeoutMs": 30000},
"payloadConfig": {
"parameters": "{\"operation\":\"list_issues\",\"organizationSlug\":\"valkyr-labs\",\"projectSlug\":\"api-0\",\"query\":\"is:unresolved level:error\",\"limit\":100}"
}
}
The integration-account value is symbolic. Persisted workflows use the generated relationship and never a plaintext token.
Operations
| Operation | Sentry behavior | Side effect |
|---|---|---|
list_organizations | Lists organizations visible to the token. | Read-only; safe retries. |
list_teams | Lists teams in one organization. | Read-only; safe retries. |
list_projects | Lists organization projects. | Read-only; safe retries. |
get_project | Reads one project by organization/project slug. | Read-only; safe retries. |
list_issues | Searches project issues with optional query and statistics window. | Read-only; safe retries. |
get_issue | Reads one issue by numeric ID. | Read-only; safe retries. |
update_issue | Updates only allowlisted issue state/assignment flags. | Audit mutation; single attempt. |
list_events | Lists project events, optionally with full payloads. | Read-only; safe retries. |
get_event | Reads one project event. | Read-only; safe retries. |
list_releases | Lists organization releases, optionally filtered to a project slug. | Read-only; safe retries. |
get_release | Reads one organization release by version. | Read-only; safe retries. |
create_release | Creates one correlated organization release. | New release; single attempt. |
Errors and Failure Modes
| Code | Typical cause | Retryable | Resolution |
|---|---|---|---|
VALIDATION_ERROR | Missing/invalid slug, ID, cursor, update, version, project list, field, JSON, or release URL. | No | Correct input; no unsafe request was sent. |
UNSUPPORTED_OPERATION | Unknown operation. | No | Select a documented operation. |
INTEGRATION_ACCOUNT_REQUIRED | No bound account. | No | Bind a Sentry IntegrationAccount. |
INTEGRATION_ACCOUNT_NOT_READY | Account is closed/error. | No | Repair or reconnect the account. |
SENTRY_HTTP_400 | Provider rejected a filter, field, or release body. | No | Correct the bounded request. |
SENTRY_HTTP_401 / 403 | Token invalid/expired or missing scope. | No | Rotate the token or grant minimum permissions. |
SENTRY_HTTP_404 | Resource is absent or invisible. | No | Re-run discovery with the same account. |
SENTRY_HTTP_429 / 5xx | Rate limit or transient provider failure. | Yes for reads | Honor Retry-After or X-Sentry-Rate-Limits; reconcile writes first. |
NETWORK_ERROR | Timeout, DNS, TLS, or connectivity failure. | Yes for reads | Verify connectivity; inspect provider state before repeating a write. |
RESPONSE_TOO_LARGE | Response exceeded 5 MiB. | No | Narrow the query or lower the limit. |
INVALID_PROVIDER_RESPONSE | List response was not an array or a cursor repeated. | No | Use requestId and verify API compatibility. |
Example
Resolve one verified issue after release evidence shows the fix is active:
{
"operation": "update_issue",
"issueId": "4388671590",
"issueStatus": "resolved",
"assignedTo": "team:platform",
"requestId": "api-0-release-20260808"
}
Expected result:
{
"status": "success",
"operation": "update_issue",
"attempts": 1,
"httpStatus": 200,
"id": "4388671590",
"shortId": "API-0-221",
"data": {
"id": "4388671590",
"shortId": "API-0-221",
"status": "resolved"
}
}
Notes
- Pagination: Sentry uses cursor data in the
Linkresponse header. The module extracts only the opaquecursorquery value, sends it back to the fixed Sentry host, rejects repeated/malformed cursors, and stops at the requested limit or 10,000 resources. - Rate limits: reads retry HTTP 408, 429, 500, 502, 503, and 504 according to
RetryPolicy, honoringRetry-Afterand the delay portion ofX-Sentry-Rate-Limits. Writes never retry automatically. - API limits: provider responses are capped at 5 MiB, structured mutations at 512 KiB, project lists at 100 slugs, and release versions at 200 characters.
- Search behavior: Sentry applies its own issue-search grammar and default unresolved filter semantics. Keep queries narrow and use the same filters when resuming from
nextCursor. - Idempotency: issue updates and release creation are single-attempt. Use a caller-owned
requestIdand deterministic releaseversion; reconcile Sentry state before repeating an ambiguous timeout. - Destructive behavior: this release does not expose issue, project, team, organization, or release deletion. Issue state changes are reversible through another explicit update.
- Public state:
isPubliccontrols Sentry's issue-sharing behavior only. It does not grant ValkyrAI RBAC/ACL access and must not be treated as an authorization shortcut. - Security: credentials remain in IntegrationAccount SecureFields. Fixed-host routing, encoded path segments, allowlisted mutation fields, bounded responses, and redacted errors prevent arbitrary routing or token reflection.
- External verification: request construction, cursor pagination, validation, retry safety, redaction, payload mapping, and metadata discovery are deterministic local tests. Live Sentry roles, scopes, rate limits, and release behavior require separately authorized provider credentials and are not exercised in repository tests.
- Deferred operations: organization/team/project mutations, issue deletion/bulk updates, event attachments, release update/delete/file management, repositories, deploys, monitors, alerts, metric queries, webhooks/triggers, OAuth refresh, and arbitrary raw requests.
- Functional references: n8n Sentry node source and Sentry API reference.