{"record":{"id":"66f4c931c717c3cf","repo":"AdguardTeam/AdGuardHome","slug":"storing-session-w","errorCode":null,"errorMessage":"storing session: %w","messagePattern":"storing session: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/aghuser/sessionstorage.go","lineNumber":335,"sourceCode":"\n\treturn data\n}\n\n// type check\nvar _ SessionStorage = (*DefaultSessionStorage)(nil)\n\n// New implements the [SessionStorage] interface for *DefaultSessionStorage.\nfunc (ds *DefaultSessionStorage) New(ctx context.Context, u *User) (s *Session, err error) {\n\ts = &Session{\n\t\tToken:     NewSessionToken(),\n\t\tUserID:    u.ID,\n\t\tUserLogin: u.Login,\n\t\tExpire:    ds.clock.Now().Add(ds.sessionTTL),\n\t}\n\n\terr = ds.store(s)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"storing session: %w\", err)\n\t}\n\n\tds.mu.Lock()\n\tdefer ds.mu.Unlock()\n\n\tds.sessions[s.Token] = s\n\n\treturn s, nil\n}\n\n// store saves a web user session in the bbolt database.\nfunc (ds *DefaultSessionStorage) store(s *Session) (err error) {\n\ttx, err := ds.db.Begin(true)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"starting transaction: %w\", err)\n\t}\n\n\tneedRollback := true","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/aghuser/sessionstorage.go#L317-L353","documentation":"Returned by DefaultSessionStorage.New (called from addSession) when persisting a newly created session via store() fails. The wrapped error is usually one of the transaction errors (begin/create-bucket/put/commit) from bbolt.","triggerScenarios":"User logs in and the code path addSession -> New -> store fails: db file unwritable, disk full, db locked by another process, or bucket creation rejected.","commonSituations":"Disk full; read-only volume; running two instances on the same work dir; permissions changed after moving the data dir (Docker volume issues).","solutions":["Free disk space and ensure the data directory is writable by the process user","Ensure only one instance uses the work directory","Inspect the wrapped error for the exact bbolt stage (begin/put/commit) and address that","Restart the service if the file lock is stale"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// ensure the data dir is writable before login flows\nif err := checkWritable(filepath.Join(workDir, \"sessions.db\")); err != nil { return err }","typeGuard":null,"tryCatchPattern":"// surface to the login handler as a 500; login cannot proceed without persistence\nif err := storage.New(ctx, u); err != nil { http.Error(w, \"session storage unavailable\", http.StatusInternalServerError) }","preventionTips":["Disk space alerts on the data volume","Single instance per work dir","Health-check writability at startup"],"tags":["bbolt","sessions","login","storage"],"backgroundTag":"database-write-failed","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}