abhigyanpatwari/GitNexus · warning · GitNexusRcError

must be an array of strings.

Error message

${source} must be an array of strings.

What it means

The wiki-generation LLM client detected an Azure endpoint (provider === 'azure' or an Azure-matching baseUrl) whose URL uses the legacy `/deployments/<name>/...` format, but no api-version is set. Azure requires the api-version query parameter on legacy deployment URLs; requests without it fail at the API. The client warns and proceeds — the fix is to add an API version or switch to the v1 URL format.

Solutions

  1. Pass the API version: --api-version 2024-10-21 (or the AZURE_API_VERSION env/config field)
  2. Or switch baseUrl to the v1 API format, which does not need the per-request api-version
  3. Verify the deployment name in the URL still exists in the Azure resource
  4. Re-run wiki generation after setting it — the request itself would have been rejected without the parameter

Example fix

# before
npx gitnexus wiki --provider azure \
  --base-url https://myres.openai.azure.com/deployments/gpt-4o/chat/completions

# after
npx gitnexus wiki --provider azure \
  --base-url https://myres.openai.azure.com/deployments/gpt-4o/chat/completions \
  --api-version 2024-10-21
Defensive patterns

Strategy: validation

Validate before calling

// before building the client: normalize Azure config so the request cannot 400
const isLegacyAzureDeploymentsUrl = (baseUrl: string): boolean =>
  /\/deployments\//.test(baseUrl);
if (config.provider === 'azure' || isAzureProvider(config.baseUrl)) {
  if (isLegacyAzureDeploymentsUrl(config.baseUrl) && !config.apiVersion) {
    config = { ...config, apiVersion: config.apiVersion ?? '2024-10-21' };
  }
}

Type guard

const isAzureLegacyConfig = (c: LlmConfig): boolean =>
  (c.provider === 'azure' || isAzureProvider(c.baseUrl)) &&
  c.baseUrl.includes('/deployments/') &&
  !c.apiVersion;

Prevention

When it happens

Trigger: isAzureProvider(config.baseUrl) is true and config.baseUrl.includes('/deployments/') while config.apiVersion is unset — e.g. baseUrl like https://<res>.openai.azure.com/deployments/<dep>/chat/completions with AZURE_API_VERSION (or --api-version) missing.

Common situations: Copying a legacy Azure OpenAI endpoint from older docs into wiki-generation config; migrating configs between v1 (`/openai/v1/...`) and legacy URL styles; API version env var dropped when moving from one environment to another.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-08-20). Data as JSON: /api/errors/ca8ac4810b4e1f0d. Report an issue: GitHub.

Appendix: source

Thrown at gitnexus/src/cli/analyze-config.ts:246

      // inside `gitnexus://repo/${name}/…` code spans, so a Markdown-significant
      // character would break those spans or inject emphasis/links/HTML into
      // agent-instruction content (#1996 tri-review P1). `_` is intentionally
      // allowed (legitimate in repo names; intraword `_` is not emphasis).
      // embeddingDevice (the other `string`-kind option) only ever holds a
      // fixed device token, so this guard never rejects a valid value there.
      if (/[`*[\]<>]/.test(trimmed)) {
        throw new GitNexusRcError(
          `${source} must not contain Markdown-significant characters (\` * [ ] < >).`,
        );
      }
      return trimmed;
    }
    case 'string-array': {
      // Generic shared validator — `source` already names the config key, so
      // messages here stay key-agnostic (no fetch-wrapper coupling in the
      // shared normalizer; #1589/#1852 review F7).
      if (!Array.isArray(value)) {
        throw new GitNexusRcError(`${source} must be an array of strings.`);
      }
      const names: string[] = [];
      for (const item of value) {
        if (typeof item !== 'string') {
          throw new GitNexusRcError(`${source} entries must all be strings.`);
        }
        const trimmed = item.trim();
        if (!trimmed) {
          throw new GitNexusRcError(`${source} entries must not be empty.`);
        }
        assertNoHiddenChars(trimmed, source);
        // Values may be interpolated into a RegExp downstream. Restrict to
        // identifier / member-access shapes so a config value can never smuggle
        // regex metacharacters into a consumer.
        if (!/^[A-Za-z_$][A-Za-z0-9_$.]*$/.test(trimmed)) {
          throw new GitNexusRcError(
            `${source} entry "${trimmed}" must be an identifier or member name ` +
              `(letters, digits, _, $, . — e.g. "client.get").`,

View on GitHub (pinned to ac9a4e9abd)