{"record":{"id":"36e088a8760d4371","repo":"chenhg5/cc-connect","slug":"another-cc-connect-instance-is-already-running-wit","errorCode":null,"errorMessage":"another cc-connect instance is already running with config %s","messagePattern":"another cc-connect instance is already running with config (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cc-connect/instance_lock.go","lineNumber":57,"sourceCode":"\n\t// Open/create the lock file\n\tf, err := os.OpenFile(lockPath, os.O_CREATE|os.O_RDWR, 0644)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot open lock file: %w\", err)\n\t}\n\n\t// Try to acquire exclusive lock (non-blocking)\n\terr = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)\n\tif err != nil {\n\t\t// Lock is held by another process\n\t\tf.Close()\n\n\t\t// Try to read PID from lock file for better error message\n\t\tpid := readPIDFromLockFile(lockPath)\n\t\tif pid > 0 {\n\t\t\treturn nil, fmt.Errorf(\"another cc-connect instance is already running (PID %d) with config %s\", pid, configPath)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"another cc-connect instance is already running with config %s\", configPath)\n\t}\n\n\t// Write our PID to the lock file for diagnostics\n\tpid := os.Getpid()\n\t_ = f.Truncate(0)\n\t_, _ = f.Seek(0, 0)\n\tfmt.Fprintf(f, \"%d\\n\", pid)\n\n\treturn &InstanceLock{\n\t\tfile:     f,\n\t\tpath:     lockPath,\n\t\tacquired: true,\n\t}, nil\n}\n\n// Release releases the instance lock. It is safe to call multiple times.\nfunc (l *InstanceLock) Release() {\n\tif l == nil || !l.acquired {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/cmd/cc-connect/instance_lock.go#L39-L75","documentation":"Same contention path as the PID variant: flock was held by another process, but readPIDFromLockFile could not recover a positive PID, so the error omits the PID and names only the config path. It still means another (or stale) instance holds the instance lock for this config.","triggerScenarios":"AcquireInstanceLock fails on syscall.Flock(LOCK_EX|LOCK_NB) and readPIDFromLockFile(lockPath) returns <= 0 — e.g. empty, corrupt, or unreadable lock file contents (PID write raced or file was truncated).","commonSituations":"The lock file was created by a process that died before writing its PID; a root-owned or unreadable lock file; manually truncated lock file.","solutions":["Find the holder yourself: use lsof <configDir>/.<configBase>.lock or fuser to identify the locking process.","If no live process holds it, delete the lock file and restart cc-connect.","Check lock file readability/ownership (ls -l) and fix if owned by another user/root."],"exampleFix":"// shell\n// before\ncc-connect  # another instance is already running with config ...\n// after\nlsof ~/.config/cc-connect/.config.toml.lock  # confirm no holder, then\nrm ~/.config/cc-connect/.config.toml.lock && cc-connect","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"lock, err := AcquireInstanceLock(configPath)\nif err != nil && strings.HasPrefix(err.Error(), \"another cc-connect instance is already running\") {\n    // PID unknown — find holder externally, then decide stop vs remove lock\n    exec.Command(\"sh\", \"-c\", \"lsof \"+lockPath).Run()\n    os.Exit(1)\n}","preventionTips":["Treat this message as 'unknown holder' — investigate with lsof/fuser before deleting the lock.","Avoid manually editing/truncating lock files.","Ensure the process that creates the lock also writes its PID before any long work."],"tags":["singleton","file-lock","process","cli"],"backgroundTag":"instance-already-running","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}