infiniflow/ragflow · error · RuntimeError

Provide either an API token or both email/password for Jira

Error message

Provide either an API token or both email/password for Jira authentication.

What it means

A RuntimeError from the test/CLI entrypoint validating the credentials dict: it requires either jira_api_token, or the pair (jira_user_email or jira_username) plus jira_password. The Jira client supports two auth schemes and this check rejects credentials that satisfy neither before any network call is made.

Source

Thrown at common/data_source/jira/connector.py:962

            "start_ts": args.start_ts,
            "end_ts": args.end_ts,
            "include_comments": args.include_comments,
            "include_attachments": args.include_attachments,
            "attachment_size_limit": args.attachment_size_limit,
            "credentials": {
                "jira_user_email": args.user_email,
                "jira_api_token": args.api_token,
                "jira_password": args.password,
            },
        }

    base_url = config.get("base_url")
    credentials = config.get("credentials", {})

    if not base_url:
        raise RuntimeError("Jira base URL must be provided via config or CLI arguments.")
    if not (credentials.get("jira_api_token") or ((credentials.get("jira_user_email") or credentials.get("jira_username")) and credentials.get("jira_password"))):
        raise RuntimeError("Provide either an API token or both email/password for Jira authentication.")

    connector_options = {
        key: value
        for key, value in (
            ("include_comments", config.get("include_comments")),
            ("include_attachments", config.get("include_attachments")),
            ("attachment_size_limit", config.get("attachment_size_limit")),
            ("labels_to_skip", config.get("labels_to_skip")),
            ("comment_email_blacklist", config.get("comment_email_blacklist")),
            ("scoped_token", config.get("scoped_token")),
            ("timezone_offset", config.get("timezone_offset")),
        )
        if value is not None
    }

    documents = test_jira(
        base_url=base_url,
        project_key=config.get("project_key"),

View on GitHub (pinned to 554fb1133a)

Solutions

  1. For Jira Cloud supply --user-email and --api-token (a token created at id.atlassian.com/manage-profile/security/api-tokens).
  2. For Data Center/self-hosted with password auth supply username (or email) AND password together.
  3. Print/inspect the credentials keys (never the values) right before the call to confirm none are empty strings — empty strings fail the truthiness check.
  4. If using scoped tokens, ensure they flow into jira_api_token (or scoped_token option) rather than a password field.

Example fix

# before
config['credentials'] = {'jira_user_email': 'you@org.com'}  # RuntimeError: Provide either an API token or both email/password

# after
config['credentials'] = {'jira_user_email': 'you@org.com', 'jira_api_token': os.environ['JIRA_API_TOKEN']}
Defensive patterns

Strategy: validation

Validate before calling

creds = config.get("credentials", {})
has_token = bool(creds.get("jira_api_token"))
has_password_pair = bool((creds.get("jira_user_email") or creds.get("jira_username")) and creds.get("jira_password"))
if not (has_token or has_password_pair):
    raise ValueError("need jira_api_token, or (jira_user_email|jira_username)+jira_password")

Prevention

When it happens

Trigger: Running the test/CLI flow where credentials contain only a password without a user identity, only an email with no token/password, or nothing at all — e.g. passing --api-token as an empty string while omitting --user-email/--password.

Common situations: Confusing Jira Cloud (email + API token) with Data Center (username + password) auth and passing a mix; empty-string env vars expanding into the args; rotating to scoped tokens without setting jira_api_token; shell quoting dropping the value.

Understand the failure class

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/34dd4365a8be9037. Report an issue: GitHub.