Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"uri" keyNotFound Error while generating a response #213

Open
PallavAg opened this issue Dec 15, 2024 · 2 comments
Open

"uri" keyNotFound Error while generating a response #213

PallavAg opened this issue Dec 15, 2024 · 2 comments
Assignees

Comments

@PallavAg
Copy link

Description of the bug:

Using the Gemini iOS SDK (Version 0.5.6), I'm getting a Swift.DecodingError.keyNotFound for "uri" in the response.
This seems to happen about 50% of the time, whereas the other 50% the response comes through as expected.

Actual vs expected behavior:

Swift code being run:

print("Sending Request.")
var model = GenerativeModel(name: "gemini-2.0-flash-exp", apiKey: "<API_KEY_HERE>")
let response = try await model.generateContent("Run a Python program any random one") // This throws the error
print("Response: \(response.text ?? "N/A")")

Expected response:

Okay, here is a simple Python program...

Actual Response

[GoogleGenerativeAI] Error decoding server JSON: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "uri", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "candidates", intValue: nil), _CodingKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "citationMetadata", intValue: nil), CodingKeys(stringValue: "citationSources", intValue: nil), _CodingKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"uri\", intValue: nil) (\"uri\").", underlyingError: nil))

Same error but formatted for readability:

[GoogleGenerativeAI] Error decoding server JSON: 
Swift.DecodingError.keyNotFound(
    CodingKeys(stringValue: "uri", intValue: nil), 
    Swift.DecodingError.Context(
        codingPath: [
            CodingKeys(stringValue: "candidates", intValue: nil), 
            _CodingKey(stringValue: "Index 0", intValue: 0), 
            CodingKeys(stringValue: "citationMetadata", intValue: nil), 
            CodingKeys(stringValue: "citationSources", intValue: nil), 
            _CodingKey(stringValue: "Index 0", intValue: 0)
        ], 
        debugDescription: "No value associated with key CodingKeys(stringValue: \"uri\", intValue: nil) (\"uri\").", 
        underlyingError: nil
    )
)

Any other information you'd like to share?

This happens on multiple devices and seems to be new behavior despite unchanged code. Happens both when streaming and not streaming the response.

From the logs, the citationSources field seems to be where the problem comes from.

Here are the full logs with verbose logging enabled:

[GoogleGenerativeAI] Verbose logging enabled.
[GoogleGenerativeAI] Creating request with the equivalent cURL command:
----- cURL command -----
curl -H 'Content-Type: application/json' -H 'x-goog-api-key: <REDACTED_API_KEY>' -H 'x-goog-api-client: genai-swift/0.5.6' 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent' -d '{"model":"models\/gemini-2.0-flash-exp","contents":[{"role":"user","parts":[{"text":"Write a Python program any random one"}]}]}'
------------------------
[GoogleGenerativeAI] JSON response: {
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "Okay, let's create a Python program that generates a random password.  This is a classic, useful example, and it's relatively straightforward to implement.\n\n```python\nimport random\nimport string\n\ndef generate_random_password(length=12):\n    \"\"\"Generates a random password of the specified length.\n\n    Args:\n        length: The desired length of the password (default is 12).\n\n    Returns:\n        A string representing the generated password.\n    \"\"\"\n\n    if length \u003c 1:\n        return \"\"  # Return an empty string for invalid lengths\n\n    characters = string.ascii_letters + string.digits + string.punctuation\n    password = ''.join(random.choice(characters) for _ in range(length))\n    return password\n\n\nif __name__ == \"__main__\":\n    password_length = 16 # You can change this to the desired length\n    random_password = generate_random_password(password_length)\n    print(f\"Generated Random Password (Length {password_length}): {random_password}\")\n\n    # Example of another password with default length\n    default_password = generate_random_password()\n    print(f\"Generated Random Password (Default Length 12): {default_password}\")\n```\n\n**Explanation:**\n\n1.  **Import Modules:**\n    *   `random`: This module provides functions for generating random numbers and making random selections.\n    *   `string`: This module provides useful string constants like `ascii_letters`, `digits`, and `punctuation` which we use for the characters to use to build the password.\n\n2.  **`generate_random_password(length=12)` Function:**\n    *   **`length` Parameter:** This is an optional parameter specifying the length of the password to generate, defaults to 12 if not specified by the caller.\n    *   **Error Handling:** It checks if `length` is a valid number greater than 0, if not it returns an empty string to represent an invalid length.\n    *   **Character Set:** \n        *  It creates a string `characters` containing all the desired character types: uppercase letters, lowercase letters, digits and punctuation symbols.\n    *   **Password Generation:**\n        *   It uses a list comprehension (`random.choice(characters) for _ in range(length)`) to generate a list of random characters by making `length` random choices from the `characters` string.\n        *   It uses `''.join(...)` to concatenate the random characters into a single string.\n    *   **Return Value:** The function returns the generated random password string.\n\n3.  **`if __name__ == \"__main__\":` Block:**\n    *   This block is the entry point of the script when you run it.\n    *   **Setting Password Length:** A length for the generated password is specified in the `password_length` variable.\n    *   **Password Generation and Output:** It calls the `generate_random_password()` function, prints the resulting password along with its length using an f-string.\n    *  **Example using default length**: Then the program calls `generate_random_password()` without specifying a length to show how the default works.\n\n**How to Run:**\n\n1.  Save the code as a Python file (e.g., `random_password.py`).\n2.  Open a terminal or command prompt.\n3.  Navigate to the directory where you saved the file.\n4.  Run the script using the command: `python random_password.py`\n\nEach time you run it, you'll get a new, randomly generated password.\n**Important Notes:**\n\n*   **Security:** This password generator is a basic example for learning. For highly secure password generation, you might want to investigate using the `secrets` module in Python for more cryptographically secure random number generation and handling, especially if generating for any kind of sensitive data.\n*   **Complexity:** If you need to generate passwords that meet specific complexity rules (e.g., at least one uppercase letter, one digit, etc.), you will need to add more logic to the code to enforce these rules by verifying after generation, or building the password step by step.\n*   **Usability**: While the passwords generated by this program are secure in terms of being hard to guess at random, they may be difficult to remember and should not be saved in plain text. If you need to remember these passwords, you might be better off using a password manager application.\n\nThis should give you a good starting point. Let me know if you have any other questions or if you want to try other random programs!\n"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "safetyRatings": [
        {
          "category": "HARM_CATEGORY_HATE_SPEECH",
          "probability": "NEGLIGIBLE"
        },
        {
          "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
          "probability": "NEGLIGIBLE"
        },
        {
          "category": "HARM_CATEGORY_HARASSMENT",
          "probability": "NEGLIGIBLE"
        },
        {
          "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
          "probability": "NEGLIGIBLE"
        }
      ],
      "citationMetadata": {
        "citationSources": [
          {
            "startIndex": 541,
            "endIndex": 703,
            "uri": "https://osintteam.blog/6-simple-osint-python-scripts-to-add-to-your-toolkit-a704e6b29671"
          },
          {
            "startIndex": 567,
            "endIndex": 751,
            "uri": "https://worktile.com/kb/ask/2222986.html"
          },
          {
            "startIndex": 3063,
            "endIndex": 3217
          }
        ]
      },
      "avgLogprobs": -0.53625421075372248
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 8,
    "candidatesTokenCount": 999,
    "totalTokenCount": 1007
  },
  "modelVersion": "gemini-2.0-flash-exp"
}


[GoogleGenerativeAI] Error decoding server JSON: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "uri", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "candidates", intValue: nil), _CodingKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "citationMetadata", intValue: nil), CodingKeys(stringValue: "citationSources", intValue: nil), _CodingKey(stringValue: "Index 2", intValue: 2)], debugDescription: "No value associated with key CodingKeys(stringValue: \"uri\", intValue: nil) (\"uri\").", underlyingError: nil))
@morganchen12
Copy link
Collaborator

I was able to repro this bug. Looks like the server is returning invalid citations. Let me check with the backend team if this is expected.

@morganchen12
Copy link
Collaborator

This fix will be delayed since some of our team is on vacation for the holidays.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants