vxcontrol/pentagi · error

failed to get screenshot: %w

Error message

failed to get screenshot: %w

What it means

GetScreenshot fetches a single screenshot row by ID via db.GetScreenshot and wraps any query failure as "failed to get screenshot: %w". Note this fires for ALL database errors including pgx's no-rows condition — a genuinely missing screenshot ID produces this same wrapped error rather than a distinct not-found sentinel.

Source

Thrown at backend/pkg/controller/screenshot.go:58

		Name:      database.SanitizeUTF8(name),
		Url:       database.SanitizeUTF8(url),
		FlowID:    sw.flowID,
		TaskID:    database.Int64ToNullInt64(taskID),
		SubtaskID: database.Int64ToNullInt64(subtaskID),
	})
	if err != nil {
		return 0, fmt.Errorf("failed to create screenshot: %w", err)
	}

	sw.pub.ScreenshotAdded(ctx, screenshot)

	return screenshot.ID, nil
}

func (sw *flowScreenshotWorker) GetScreenshot(ctx context.Context, screenshotID int64) (database.Screenshot, error) {
	screenshot, err := sw.db.GetScreenshot(ctx, screenshotID)
	if err != nil {
		return database.Screenshot{}, fmt.Errorf("failed to get screenshot: %w", err)
	}

	return screenshot, nil
}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Unwrap and check for pgx.ErrNoRows / sql.ErrNoRows to distinguish not-found from real failures.
  2. Verify the screenshot ID exists (e.g. query the screenshots table directly).
  3. Check DB connectivity if many screenshots fail at once.
  4. Extend the caller's context timeout if the query is timing out.

Example fix

// before: all failures treated the same
shot, err := sw.GetScreenshot(ctx, id)

// after: distinguish not-found
shot, err := sw.GetScreenshot(ctx, id)
if err != nil {
    if errors.Is(err, pgx.ErrNoRows) {
        return nil, ErrScreenshotNotFound
    }
    return nil, err
}
Defensive patterns

Strategy: type-guard

Validate before calling

// check existence first if your query layer exposes it
var exists bool
err := db.QueryRow("SELECT EXISTS(SELECT 1 FROM screenshots WHERE id=$1)", id).Scan(&exists)

Type guard

func isScreenshotNotFound(err error) bool {
    return errors.Is(err, pgx.ErrNoRows) || errors.Is(err, sql.ErrNoRows)
}

Try / catch

shot, err := sw.GetScreenshot(ctx, id)
if err != nil {
    if isScreenshotNotFound(err) {
        return nil, ErrScreenshotNotFound // 404, not 500
    }
    return nil, err
}

Prevention

When it happens

Trigger: Calling GetScreenshot(ctx, screenshotID) with a database error: connection failure, context cancellation, or the ID not existing in the screenshots table (sql.ErrNoRows / pgx.ErrNoRows wrapped).

Common situations: UI requesting a screenshot that was deleted or belongs to another flow; stale ID after data retention cleanup; DB connectivity issues; typo'd or forged screenshot ID from a client.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/ffcf6f31aebd9daf. Report an issue: GitHub.