--- title: "Dagster" description: "Connect Dagster so OpenSRE can investigate pipeline run failures, asset materialization errors, and sensor or schedule misfires during incidents" --- OpenSRE uses the Dagster GraphQL API to investigate data-pipeline incidents, fetching recent runs and their status, the full event log and root-cause exception for a failed run, asset materialization history, and sensor or schedule tick history. Works against both Dagster OSS (`dagster dev` and self-hosted dagster-webserver) and Dagster+ (the SaaS). ## Prerequisites - A reachable dagster-webserver instance: - **Dagster OSS:** run `dagster dev -f jobs.py` locally or deploy `dagster-webserver` to your infra. Default port `3000`. - **Dagster+:** an active deployment, e.g. `https://.dagster.cloud/` or `https://..dagster.cloud/`. - Network access from the OpenSRE environment to the webserver - For Dagster+: a **User Token** generated under **Organization Settings → Tokens → User Tokens** (not an Agent Token; Agent Tokens authenticate Hybrid agents and are rejected by the GraphQL endpoint) ## Setup ### Option 1: Onboarding wizard ```bash opensre onboard ``` Pick **Dagster** from the integration menu. The wizard asks for: - **Dagster webserver URL** — `http://localhost:3000` for OSS local dev, or `https://.dagster.cloud/` for Dagster+ (the client appends `/graphql` itself, so either form is fine) - **Dagster API token** — required for Dagster+; leave blank for unauthenticated OSS The wizard validates the endpoint with a GraphQL `version` probe before saving, writes `DAGSTER_ENDPOINT` to your `.env`, and persists the API token (when provided) to your system keychain. ### Option 2: Legacy CLI ```bash opensre integrations setup dagster ``` You will be prompted for the GraphQL endpoint and (optional) API token. ### Option 3: Manual configuration Add to your `.env`: ```bash DAGSTER_ENDPOINT=https://your-org.dagster.cloud/prod DAGSTER_API_TOKEN=... ``` | Variable | Default | Description | | --- | --- | --- | | `DAGSTER_ENDPOINT` | — | **Required.** Base URL of the dagster-webserver. The client appends `/graphql` itself, so paste any of `https://host/deployment`, `https://host/deployment/`, `https://host/deployment/graphql` — all collapse to the same canonical base. | | `DAGSTER_API_TOKEN` | _(empty)_ | Required for Dagster+ deployments. Leave empty for unauthenticated local OSS Dagster. Sent as the `Dagster-Cloud-Api-Token` header. | Credentials configured via Options 1 and 2 are also persisted to `~/.opensre/integrations.json` with `0o600` permissions: ```json { "version": 1, "integrations": [ { "id": "dagster-prod", "service": "dagster", "status": "active", "credentials": { "endpoint": "https://your-org.dagster.cloud/prod", "api_token": "..." } } ] } ``` ## Where to find your Dagster+ token and endpoint **Endpoint:** look at the URL in your browser when logged into Dagster+. It is the part up through the deployment name, e.g. `https://acme.dagster.cloud/prod` if the address bar shows `https://acme.dagster.cloud/prod/runs`. EU accounts use a regional subdomain such as `https://acme.eu.dagster.cloud/prod`. Trailing `/graphql` is accepted and stripped automatically. **API token:** 1. Click the user menu (your icon) → **Organization Settings** 2. Open the **Tokens** tab 3. Click **+ Create user token**, give it a name like `opensre-integration` 4. Copy the token immediately (Dagster+ shows it once and never again) User Tokens inherit the user's per-deployment role. A user account that has at least the Viewer role on the target deployment is sufficient for read-only investigation queries. > **Token type matters.** Use a **User Token**, not an **Agent Token**. Agent Tokens authenticate Hybrid agents talking to the Agents API and are rejected (HTTP 401) by the GraphQL endpoint. ## Investigation tools When OpenSRE investigates a Dagster-related alert, five diagnostic tools are available: - **List runs** — recent pipeline/job runs with status, job name, timestamps, and pre-computed duration; filterable by status and job name - **Get run logs** — event log for a specific run with `ExecutionStepFailureEvent` and `RunFailureEvent` entries; surfaces user-code exceptions from `error.cause` (e.g. the `ValueError` underlying Dagster's `DagsterExecutionStepExecutionError` wrapper) and pre-counts multi-step failures - **List assets with materialization** — Dagster assets with their latest materialization timestamp + run id; useful for spotting stale or never-materialized assets - **List sensor ticks** — recent tick history for a sensor (identified by full `SensorSelector` triplet: repository location, repository, sensor name) - **List schedule ticks** — recent tick history for a schedule (identified by full `ScheduleSelector` triplet: repository location, repository, schedule name) ## Verify ```bash opensre integrations verify dagster ``` Expected output: ``` SERVICE SOURCE STATUS DETAIL dagster local env passed Connected to Dagster version 1.13.6. ``` The verifier issues a `query { version }` probe against the configured endpoint and reports the running Dagster version on success. ## Troubleshooting | Symptom | Fix | | --- | --- | | **HTTP 401 with HTML body** | The Dagster+ edge proxy rejected the request. Most likely causes: (1) the token is an Agent Token not a User Token; (2) the user owning the token lacks role on the target deployment; (3) the token was revoked or regenerated. Verify under **Organization Settings → Tokens → User Tokens** and confirm the user has access to the deployment in the URL. | | **Invalid JSON in response: Expecting value** | The endpoint was reached but did not respond with JSON. Usually means the URL is wrong (e.g. you pasted a path that hits the Dagster+ UI instead of the GraphQL endpoint). The client appends `/graphql` automatically; paste only the base URL through the deployment name. | | **Request to Dagster failed: Connection refused** | dagster-webserver is not running at the configured endpoint. Start it with `dagster dev -f jobs.py` for local OSS, or check the Dagster+ deployment status. | | **`runsOrError.__typename == InvalidPipelineRunsFilterError`** | The status filter passed an unrecognized `RunStatus` value. Valid values: `QUEUED`, `NOT_STARTED`, `MANAGED`, `STARTING`, `STARTED`, `SUCCESS`, `FAILURE`, `CANCELING`, `CANCELED`. | | **`logsForRun` returns `RunNotFoundError`** | The run id does not exist on this deployment. Confirm the run id and the deployment slug in the endpoint match. | | **Sensor query returns `SensorNotFoundError`** | The `SensorSelector` triplet (`repository_location_name`, `repository_name`, `sensor_name`) did not match a sensor in the deployment. List sensors in the Dagster UI to confirm the exact names. | | **Schedule query returns `ScheduleNotFoundError`** | The `ScheduleSelector` triplet (`repository_location_name`, `repository_name`, `schedule_name`) did not match a schedule in the deployment. List schedules in the Dagster UI to confirm the exact names. | ## Security best practices - Use a **dedicated User Token** scoped to a service-style user account when possible. Dagster+ does not have first-class service accounts; the community pattern is a separate user whose token you use. - Keep tokens out of source control — use `.env` (gitignored) or the persistent store at `~/.opensre/integrations.json`. - The GraphQL queries OpenSRE issues are **read-only**: list runs, fetch event logs, list assets, fetch sensor ticks. No mutations are sent. - Rotate tokens periodically. Tokens can be revoked from the same Organization Settings → Tokens page. - For local OSS Dagster without auth, restrict the webserver to localhost or your private network. Do not expose `dagster dev`'s default port to the internet.