{"record":{"id":"430a5134a4ab3c85","repo":"MHSanaei/3x-ui","slug":"dev-release-commit-is-unknown","errorCode":null,"errorMessage":"dev release commit is unknown","messagePattern":"dev release commit is unknown","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/web/service/panel/panel.go","lineNumber":167,"sourceCode":"// release. It is driven solely by the opt-in setting so the panel can\n// cross-grade a stable build onto the dev channel once the user enables it;\n// nothing updates without an explicit user action, so an unattended stable\n// binary with the toggle off stays on the stable channel.\nfunc devChannelActive() bool {\n\tenabled, err := (&service.SettingService{}).GetDevChannelEnable()\n\treturn err == nil && enabled\n}\n\n// getDevUpdateInfo compares the running commit against the commit recorded in the\n// rolling dev release.\nfunc getDevUpdateInfo() (*PanelUpdateInfo, error) {\n\trelease, err := fetchPanelRelease(devReleaseTag)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tlatestCommit := extractReleaseCommit(release)\n\tif latestCommit == \"\" {\n\t\treturn nil, fmt.Errorf(\"dev release commit is unknown\")\n\t}\n\tcurrentCommit := config.GetBuildCommit()\n\treturn &PanelUpdateInfo{\n\t\tChannel:         \"dev\",\n\t\tCurrentVersion:  config.GetPanelVersion(),\n\t\tCurrentCommit:   shortCommit(currentCommit),\n\t\tLatestCommit:    shortCommit(latestCommit),\n\t\tLatestVersion:   \"dev+\" + shortCommit(latestCommit),\n\t\tUpdateAvailable: !commitsEqual(currentCommit, latestCommit),\n\t}, nil\n}\n\n// StartUpdate starts the official updater using this panel's own channel\n// setting. Returns the run ID to pass to GetUpdateStatus so the caller can\n// tell this run's result apart from a stale one.\nfunc (s *PanelService) StartUpdate() (int64, error) {\n\treturn s.startUpdate(devChannelActive())\n}","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/web/service/panel/panel.go#L149-L185","documentation":"getDevUpdateInfo fetches the rolling GitHub release tagged devReleaseTag and extracts the built commit (extractReleaseCommit). If the release metadata contains no recognizable commit hash, the dev-channel update check cannot compare versions, so it errors out rather than guessing. This depends entirely on the release having been published with a commit reference (e.g. in the target_commitish/body).","triggerScenarios":"Calling GetUpdateInfo on the dev channel when the upstream dev release was created by a workflow that omitted the commit — e.g. release deleted and re-created without the hash, or a manually drafted release.","commonSituations":"Upstream repo changed its release automation; the fetched release JSON is a proxied/cached copy that stripped the commit field; checking for updates right as the dev release is being republished.","solutions":["Retry shortly after — if the upstream dev release was mid-republish, the next release carries the commit again","Inspect the release manually: gh release view <dev tag> --json targetCommitish,body to confirm a commit is present","If it persists, report upstream — the release pipeline is omitting the commit; use the stable channel meanwhile"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"info, err := panelService.GetUpdateInfo()\nif err != nil && strings.Contains(err.Error(), \"dev release commit is unknown\") {\n    // transient upstream publishing window: fall back to stable channel info or retry later\n}","preventionTips":["Treat dev-channel update checks as best-effort; keep stable as fallback","Pin deployments to stable releases in production"],"tags":["updates","github-api","dev-channel","external-dependency"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}