{"record":{"id":"eb6e7344689f5d21","repo":"multica-ai/multica","slug":"ping-database-w-eb6e73","errorCode":null,"errorMessage":"ping database: %w","messagePattern":"ping database: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/backfill_task_usage_hourly/main.go","lineNumber":93,"sourceCode":"\tif dbURL == \"\" {\n\t\tdbURL = \"postgres://multica:multica@localhost:5432/multica?sslmode=disable\"\n\t}\n\n\t// SIGINT/SIGTERM cancels ctx so an in-flight slice stops cleanly —\n\t// each slice runs in its own transaction (the window function), so\n\t// Postgres rolls back the interrupted one and the idempotent design\n\t// lets a later run resume from where this one stopped.\n\tctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)\n\tdefer stop()\n\n\tpool, err := pgxpool.New(ctx, dbURL)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"connect to database: %w\", err)\n\t}\n\tdefer pool.Close()\n\n\tif err := pool.Ping(ctx); err != nil {\n\t\treturn fmt.Errorf(\"ping database: %w\", err)\n\t}\n\n\t// Serialise against the cron rollup and any other backfill run via\n\t// advisory lock 4246 — the same id the cron entry checks with\n\t// pg_try_advisory_lock. While this backfill holds it, the cron tick\n\t// no-ops instead of racing on task_usage_hourly row locks; a second\n\t// concurrent backfill blocks here until this one finishes. The lock\n\t// is held on a dedicated session connection for the whole run.\n\tlockConn, err := pool.Acquire(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"acquire advisory-lock connection: %w\", err)\n\t}\n\tdefer lockConn.Release()\n\tif _, err := lockConn.Exec(ctx, `SELECT pg_advisory_lock(4246)`); err != nil {\n\t\treturn fmt.Errorf(\"acquire advisory lock 4246: %w\", err)\n\t}\n\tdefer func() {\n\t\t// Unlock on a fresh context so a cancelled ctx (SIGINT) does not","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/backfill_task_usage_hourly/main.go#L75-L111","documentation":"pool.Ping(ctx) failed: the pool was constructed but the first real round-trip to Postgres failed. This is the point where unreachable hosts, refused connections, DNS failures, bad credentials, and cancelled contexts actually surface. The wrapped pg error identifies which of these applies.","triggerScenarios":"Postgres not running on localhost:5432, wrong port, TLS requirements mismatched with sslmode=disable, pg_hba.conf rejecting the multica user, or SIGINT arriving before/during Ping (ctx cancelled).","commonSituations":"Dev environment without `make dev` / docker compose up for the database; connecting to a containerized Postgres that exposes 5433; k8s service name typo; database container still booting when the backfill starts.","solutions":["Verify the server is reachable: pg_isready -h <host> -p <port>","Check credentials and pg_hba.conf / SSL enforcement for the multica user","If Postgres is still starting (container/k8s), wait for readiness then re-run — the backfill is idempotent","Ensure the DSN host/port match where Postgres actually listens (docker port mapping, k8s Service)"],"exampleFix":"// before: backfill starts immediately, Ping races container startup\n\n// after (operator): wait for readiness before running the backfill\npg_isready -h localhost -p 5432 && go run ./server/cmd/backfill_task_usage_hourly","handlingStrategy":"retry","validationCode":"if err := pool.Ping(ctx); err != nil { /* server not reachable yet */ }","typeGuard":null,"tryCatchPattern":"if err := pool.Ping(ctx); err != nil {\n    return fmt.Errorf(\"ping database: %w\", err)\n}","preventionTips":["Gate the command on pg_isready or a readiness probe before starting","Keep sslmode consistent with the server's host-based auth config","The backfill is idempotent — safe to simply re-run after fixing connectivity"],"tags":["go","postgres","pgx","network","connectivity"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}