Skip to content

CXH-1990: Show why Snowflake sign-in failed instead of a bare error#137

Open
al-conductorone wants to merge 5 commits into
mainfrom
cxh-1990-baton-snowflake-sync-fails-with-a-bare-401-unauthorized
Open

CXH-1990: Show why Snowflake sign-in failed instead of a bare error#137
al-conductorone wants to merge 5 commits into
mainfrom
cxh-1990-baton-snowflake-sync-fails-with-a-bare-401-unauthorized

Conversation

@al-conductorone

Copy link
Copy Markdown
Contributor

Snowflake syncs that fail to authenticate now report the reason returned by Snowflake, instead of a generic "unauthorized" message, by reading the error detail from the failed request.

Validate/ListUsers returned a bare "code = Unauthenticated desc = 401
Unauthorized", so an expired trial or rotated key was indistinguishable
from an auth-handling defect. Pass uhttp.WithErrorResponse so the SQL API
error body ({code, message}) is decoded and surfaced in both the returned
error and the connector debug log, while keeping codes.Unauthenticated.
No user data is added to connector-side error/log text.
Admin review noted the SnowflakeError type in user_rest.go already has the
same {code, message} shape and implements uhttp.ErrorResponse. Reuse it in
ListUsers rather than introducing a duplicate statementsAPIError.
@linear-code

linear-code Bot commented Jul 21, 2026

Copy link
Copy Markdown

CXH-1990

@al-conductorone
al-conductorone requested review from a team and johnallers July 21, 2026 20:20
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Connector PR Review: CXH-1990: Show why Snowflake sign-in failed instead of a bare error

Blocking Issues: 0 | Suggestions: 0 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base ed151cb80949.
Review mode: full
View review run

Review Summary

The full PR diff was scanned for security and correctness. The change does two things: (1) surfaces Snowflake's response-body reason on auth failures by adding uhttp.WithErrorResponse(&apiErr) to the ListUsers requests and wrapping the Validate() error, and (2) migrates deprecated trait-level profile/status/created-at options to their resource-level equivalents (WithResourceProfile, WithResourceStatus, WithResourceCreatedAt, GetProfile). All migrated SDK helpers and the v2.Status_ResourceStatus enum values were verified to exist in the vendored SDK, and no remaining callers depend on the removed trait-level APIs. The new TestListUsers_SurfacesAuthFailureReason covers the 401 path. No new issues found.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

None.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found.

users, err := d.Client.ListUsers(ctx, "", 1)
if err != nil {
return nil, err
return nil, fmt.Errorf("baton-snowflake: credential validation failed: %w", err)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[LOW · optional] nice surfacing of the real auth reason. small wording thing: "credential validation failed" also labels non-credential transport failures (net/DNS/5xx) as credential problems — the wrapped %w still carries the true cause, so it's just the label. optional: soften to something like "snowflake: validation request failed: %w".

Comment thread pkg/connector/users.go
}

var opts []rs.ResourceOption
opts := []rs.ResourceOption{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[LOW · heads-up] this moves profile/status/created_at to resource-level options only (dropping the deprecated trait-level copy). fine for consumers on baton-sdk v0.20.2+, just worth a glance that the ingesting platform reads the resource-level attrs and not the old trait fields. no code change needed if it does.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants