{"record":{"id":"2c3711ff9d06fbd6","repo":"docling-project/docling","slug":"one-of-token-path-or-refresh-token-is-required","errorCode":null,"errorMessage":"One of 'token_path' or 'refresh_token' is required.","messagePattern":"One of 'token_path' or 'refresh_token' is required\\.","errorType":"validation","errorClass":"ValueError","httpStatus":422,"severity":"error","filePath":"docling/datamodel/service/sources.py","lineNumber":385,"sourceCode":"            ),\n            examples=[\n                \"./dev/google_drive_credentials.json\",\n            ],\n        ),\n    ]\n\n    credentials: Annotated[\n        Optional[GoogleDriveCredentials],\n        Field(\n            default=None,\n            description=\"OAuth 2.0 Client ID' credentials (available in Google Cloud console). One of 'credentials_path' or 'credentials' is required.\",\n        ),\n    ]\n\n    @model_validator(mode=\"after\")\n    def validate_auth_inputs(self) -> \"GoogleDriveCoordinates\":\n        if not (self.token_path or self.refresh_token):\n            raise ValueError(\"One of 'token_path' or 'refresh_token' is required.\")\n        if not (self.credentials_path or self.credentials):\n            raise ValueError(\"One of 'credentials_path' or 'credentials' is required.\")\n        return self\n","sourceCodeStart":367,"sourceCodeEnd":389,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/datamodel/service/sources.py#L367-L389","documentation":"GoogleDriveCoordinates runs a model validator requiring an OAuth token for Google Drive access: either token_path (a serialized-token file path) or refresh_token must be provided. Without one of these the coordinates cannot authenticate to Google Drive, so the model refuses to construct.","triggerScenarios":"Building a Google Drive source with only coordinates/credentials, e.g. GoogleDriveCoordinates(credentials_path='creds.json') with neither token_path nor refresh_token; the validator validate_auth_inputs raises before any network call.","commonSituations":"First-time Google Drive setup where the developer configured the OAuth client (credentials_path) but never completed the consent flow to obtain a token; environment differences where the token file path exists on the dev machine but not in the container; copy-pasting examples that omit the token fields.","solutions":["Complete the OAuth consent flow once to produce a token file and pass token_path='/path/to/token.json'.","Alternatively pass refresh_token directly if you manage tokens yourself (e.g. from a secret store).","In containers, mount or inject the token file/secret so token_path or refresh_token is always set."],"exampleFix":"# before\nsrc = GoogleDriveCoordinates(\n    file_id=\"abc123\",\n    credentials_path=\"credentials.json\",\n)\n\n# after\nsrc = GoogleDriveCoordinates(\n    file_id=\"abc123\",\n    credentials_path=\"credentials.json\",\n    token_path=\"token.json\",\n)","handlingStrategy":"validation","validationCode":"def has_gdrive_token(cfg: dict) -> bool:\n    return bool(cfg.get(\"token_path\") or cfg.get(\"refresh_token\"))\n\nassert has_gdrive_token(cfg), \"Google Drive source needs token_path or refresh_token\"","typeGuard":"def gdrive_auth_complete(cfg: dict) -> bool:\n    return bool(cfg.get(\"token_path\") or cfg.get(\"refresh_token\"))","tryCatchPattern":"try:\n    src = GoogleDriveCoordinates(**cfg)\nexcept ValidationError as e:\n    if \"token_path\" in str(e):\n        run_oauth_consent_flow()  # produce token.json, then retry\n    else:\n        raise","preventionTips":["Persist the OAuth token file next to credentials and mount both in containers.","Add startup checks that required Google Drive secrets exist before serving traffic."],"tags":["google-drive","oauth","authentication","pydantic","validation"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}