git-ecosystem/git-credential-manager · error · InteropException

-1

-1

Error message

Failed to store credentials

What it means

Same store path as error 114, but this variant is thrown when secret_password_store_sync returns false with no GError set — the write was reported unsuccessful without a descriptive error — so a generic InteropException with code -1 is thrown.

Solutions

  1. Retry the store once — transient daemon states can cause a silent false return
  2. Check keyring daemon logs (journalctl --user -u gnome-keyring) for the underlying failure
  3. Ensure you are using a standard Secret Service implementation (gnome-keyring/kwallet) and it is healthy
  4. Catch InteropException with Code == -1 to detect the no-detail failure case and surface a generic message

Example fix

// before
collection.AddOrUpdate(service, account, secret); // can throw code -1
// after
try { collection.AddOrUpdate(service, account, secret); }
catch (InteropException ex) when (ex.Code == -1) { RetryWithBackoff(() => collection.AddOrUpdate(service, account, secret)); }
Defensive patterns

Strategy: retry

Validate before calling

// Silent-failure path: no pre-validation possible; enable retry.
int attempts = 0;

Try / catch

try { collection.AddOrUpdate(s, a, secret); }
catch (InteropException ex) when (ex.Code == -1 && ++attempts < 3) { Thread.Sleep(200 * attempts); retry:; }

Prevention

When it happens

Trigger: AddOrUpdate where the native call completes without a GError but its bool result is false: daemon-side silent rejection of the store operation.

Common situations: Race with keyring daemon shutdown/restart during the store; unusual daemon implementations (e.g. keepassxc-proxy) returning failure without an error; resource exhaustion inside the daemon.

Related errors


AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11). Data as JSON: /api/errors/4196e6deeb7667ce. Report an issue: GitHub.

Appendix: source

Thrown at src/Core/Interop/Linux/SecretServiceCollection.cs:192

                    secService,
                    ref schema,
                    attributes,
                    null,
                    fullServiceName, // Use full service name as label
                    secretValue,
                    IntPtr.Zero,
                    out error);

                if (error != null)
                {
                    int code = error->code;
                    string message = Marshal.PtrToStringAuto(error->message)!;
                    throw new InteropException("Failed to store credentials", code, new Exception(message));
                }

                if (!result)
                {
                    throw new InteropException("Failed to store credentials", -1);
                }
            }
            finally
            {
                if (attributes != null) g_hash_table_destroy(attributes);
                if (secretValue != null) secret_value_unref(secretValue);
                if (error != null) g_error_free(error);
            }
        }

        public unsafe bool Remove(string service, string account)
        {
            GHashTable* attributes = null;
            GError* error = null;

            try
            {
                SecretService* secService = GetSecretService();

View on GitHub (pinned to e8ce762cd0)