{"record":{"id":"cd5fbf79566c4f0e","repo":"gastownhall/beads","slug":"failed-to-pull-from-s-s-w","errorCode":null,"errorMessage":"failed to pull from %s/%s: %w","messagePattern":"failed to pull from (.+?)/(.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/store.go","lineNumber":4275,"sourceCode":"\t} else if useCLI {\n\t\treturn pullReport{}, s.finishCLIPull(ctx, s.doltCLIPull(ctx, remote, creds))\n\t}\n\t// Cloud auth CLI routing (GH#6), including post-pull auto-resolution.\n\tif useCLI, err := s.prepareCLIRouteForCloudAuth(ctx, remote); err != nil {\n\t\treturn pullReport{}, err\n\t} else if useCLI {\n\t\treturn pullReport{}, s.finishCLIPull(ctx, s.doltCLIPull(ctx, remote, creds))\n\t}\n\t// Local file:// pulls intentionally stay on the SQL path. The matching CLI\n\t// guard is a push-only optimization; SQL pull keeps pullWithAutoResolve in\n\t// charge of metadata-only conflict repair.\n\tvar report pullReport\n\tif s.remoteUser != \"\" && remote == s.remote {\n\t\terr := withRemoteOperationEnv(creds, s.isS3Remote(ctx, remote), func() error {\n\t\t\tvar err error\n\t\t\treport, err = s.pullWithAutoResolveReporting(ctx, remote, \"CALL DOLT_PULL('--user', ?, ?, ?)\", s.remoteUser, remote, s.branch)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to pull from %s/%s: %w\", remote, s.branch, err)\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\treturn report, err\n\t}\n\terr := withRemoteOperationEnv(nil, s.isS3Remote(ctx, remote), func() error {\n\t\tvar err error\n\t\treport, err = s.pullWithAutoResolveReporting(ctx, remote, \"CALL DOLT_PULL(?, ?)\", remote, s.branch)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to pull from %s/%s: %w\", remote, s.branch, err)\n\t\t}\n\t\treturn nil\n\t})\n\treturn report, err\n}\n\n// pullWithAutoResolve executes a DOLT_PULL query with long timeout and auto-resolves\n// metadata-only merge conflicts using \"theirs\" strategy. This handles the common case","sourceCodeStart":4257,"sourceCodeEnd":4293,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/store.go#L4257-L4293","documentation":"Wraps a failure from the authenticated SQL pull route: CALL DOLT_PULL executed over a long-timeout connection with the '--user' argument (remoteUser set, pulling from the store's default remote), inside the remote's credential/S3 environment. The wrapped cause is the DOLT_PULL (or conflict auto-resolution) failure itself.","triggerScenarios":"Pull()/PullRemote() taking the SQL path where s.remoteUser != \"\" and remote == s.remote, and the DOLT_PULL stored procedure errors: auth rejection, network timeout, merge conflict not auto-resolvable, unknown remote, or branch does not exist on the remote.","commonSituations":"Expired or wrong Dolt remote credentials (remoteUser/password); remote not registered in this database; sql-server cannot reach doltremoteapi/S3; merge conflicts involving non-metadata rows; the remote branch was renamed or deleted.","solutions":["Read the wrapped cause: auth errors → refresh credentials; timeouts → check network to the remote host.","Verify the remote exists: SELECT * FROM dolt_remotes; and re-add with CALL DOLT_REMOTE('add', ...) if missing.","Confirm remoteUser/password are current (dolt sql -q \"select 1\" against the hosted remote).","If conflicts are the cause, resolve them manually or run the conflict repair path, then re-pull.","Check S3/cloud credentials in the environment when the remote is S3-backed."],"exampleFix":"// before\nerr := store.Pull(ctx) // fails: auth rejected for --user\n// after\n// refresh creds first:\n// CALL DOLT_REMOTE('add', 'origin', 'https://user:newtoken@doltremoteapi.dolthub.com/org/bd', '--force')\nerr := store.Pull(ctx)","handlingStrategy":"try-catch","validationCode":"// pre-check remote and creds:\n// SELECT name, url FROM dolt_remotes WHERE name = ?;\n// probe: db.QueryRow(\"SELECT 1\") against the hosted remote endpoint","typeGuard":null,"tryCatchPattern":"if err := store.Pull(ctx); err != nil {\n    if strings.Contains(err.Error(), fmt.Sprintf(\"failed to pull from %s/%s\", remote, branch)) {\n        log.Printf(\"pull failed, cause: %v\", errors.Unwrap(errors.Unwrap(err)))\n        // route by cause: auth → refresh creds; conflict → repair; timeout → retry\n    }\n    return err\n}","preventionTips":["Rotate hosted-Dolt credentials before expiry.","Register the remote in every clone (dolt_remotes) before pulling.","Keep remoteUser set only when the remote actually requires it.","Check egress/firewall rules for doltremoteapi and S3 endpoints."],"tags":["dolt","pull","sql","authentication","remote"],"backgroundTag":"dolt-pull-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}